astroboa-cli 0.3.0

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.
@@ -0,0 +1,224 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'astroboa-cli/command/base'
4
+ require 'rbconfig'
5
+
6
+ # setup astroboa as a system service (daemon) that automatically starts on boot
7
+ class AstroboaCLI::Command::Service < AstroboaCLI::Command::Base
8
+
9
+ LAUNCHD_CONFIG = '/Library/LaunchDaemons/com.betaconcept.astroboa.plist'
10
+
11
+ # service:setup
12
+ #
13
+ # Setups astroboa as a system service (daemon).
14
+ # It requires that you have already installed astroboa using 'astroboa-cli server:install'.
15
+ # Astroboa service will automatically start on system boot.
16
+ #
17
+ # To start and stop astroboa when it is installed as a system service use 'astroboa-cli service:start' and 'astroboa-cli service:stop'
18
+ #
19
+ # IMPORTANT NOTICE:
20
+ # When astroboa runs as a service the internallly installed JRUBY version and GEMS are used instead of the JRUBY used to run astroboa-cli.
21
+ # When astroboa is started through 'server:start' command, the same JRUBY version and GEMS used by astroboa-cli will be used.
22
+ # This behaviour shields the production server from the ruby setup that the astroboa-cli user might have and even allows to test newer ruby versions and gems
23
+ # during development (run astroboa with server:start) and use more stable ones during production (setup astroboa as a service and run it through service:start).
24
+ #
25
+ # In MAC OS X astroboa is setup as a system launchd daemon.
26
+ # Therefore, you must be authorized to use 'sudo' in order to use the 'service:setup' command.
27
+ # If you want to disable astroboa service from automatically running on each boot then change the 'RunAtLoad' key to 'false' in '/Library/LaunchDaemons/com.betaconcept.astroboa.plist'
28
+ #
29
+ # In linux astroboa is setup as an upstart service (requires ubuntu or debian or a linux distro that supports upstart)
30
+ #
31
+ def setup
32
+ error "Astroboa is running. Please first stop astoboa using 'astroboa-cli server:stop' and run the command again" if astroboa_running?
33
+ install_launchd_service if mac_os_x?
34
+ install_upstart_service if linux?
35
+ display "We do not yet support installing astroboa as a service in windows" if windows?
36
+ end
37
+
38
+ # service:unset
39
+ #
40
+ # unsets astroboa from being a system service (daemon).
41
+ #
42
+ # In MAC OS X it will unload astroboa from launchd and then remove astroboa from the list of system daemons (those that are loaded everytime the system boots).
43
+ #
44
+ # In LINUX it will unconfigure astroboa as an upstart service
45
+ #
46
+ def unset
47
+ error "Astroboa is running. Please first stop astoboa using 'astroboa-cli service:stop' and run the command again" if astroboa_running?
48
+ unset_launchd_service if mac_os_x?
49
+ unset_upstart_service if linux?
50
+ display "We do not yet support installing astroboa as a service in windows" if windows?
51
+ end
52
+
53
+
54
+ # service:start
55
+ #
56
+ # Starts astroboa service
57
+ #
58
+ # To install astroboa as a system service you should run 'astroboa-cli service:setup'
59
+ #
60
+ # In MAC OS X you may also start the service by running: 'launchctl start com.betaconcept.astroboa'
61
+ #
62
+ # In Linux you may also start the service by running: 'service astroboa start'
63
+ #
64
+ def start
65
+ error "Astroboa is already running" if astroboa_running?
66
+ start_launchd_service if mac_os_x?
67
+ end
68
+
69
+ # service:stop
70
+ #
71
+ # Stops astroboa service
72
+ #
73
+ # To setup astroboa as a system service you should run 'astroboa-cli service:setup'
74
+ #
75
+ # In MAC OS X you may also stop the service by running: 'launchctl unload /Library/LaunchDaemons/com.betaconcept.astroboa.plist'
76
+ # DO NOT use 'launchctl stop com.betaconcept.astroboa' because launchd will keep restarting the service.
77
+ # If you use 'launchctl unload /Library/LaunchDaemons/com.betaconcept.astroboa.plist' to stop the service then you may restart it by using
78
+ # astroboa-cli service:start or run 'launchctl load /Library/LaunchDaemons/com.betaconcept.astroboa.plist' and then 'launchctl start com.betaconcept.astroboa'
79
+ # In any case we recommend to use the commands provided by astroboa-cli that do all the necessary checks and remove the launchd complexity!
80
+ #
81
+ # In Linux you may also stop the service by running: 'service astroboa stop'
82
+ #
83
+ def stop
84
+ error "Astroboa is not running" unless astroboa_running?
85
+ stop_launchd_service if mac_os_x?
86
+ end
87
+
88
+ # service:check
89
+ #
90
+ # checks if astroboa is setup as a system service and whether astroboa service is running
91
+ #
92
+ def check
93
+ check_launchd_service if mac_os_x?
94
+ display "We do not yet support checking the status of astroboa service in linux and windows" if windows? || linux?
95
+ end
96
+
97
+ private
98
+
99
+ def install_launchd_service
100
+ server_configuration = get_server_configuration
101
+ astroboa_dir = server_configuration['install_dir']
102
+ temp_launchd_config = File.join(astroboa_dir, 'com.betaconcept.astroboa.plist')
103
+ log_file = File.join(astroboa_dir, 'torquebox', 'jboss', 'standalone', 'log', 'server.log')
104
+
105
+ unless launchd_service_configured?
106
+ uid = File.stat(astroboa_dir).uid
107
+ astroboa_user = Etc.getpwuid(uid).name
108
+ launchd_config_template = File.join(astroboa_dir, 'astroboa-setup-templates', 'AstroboaDaemon.plist.template')
109
+ context = {:astroboa_dir => astroboa_dir, :java_home => ENV['JAVA_HOME'], :jruby_home => File.join(server_configuration['install_dir'], 'torquebox', 'jruby'), :astroboa_user => astroboa_user}
110
+ render_template_to_file(launchd_config_template, context, temp_launchd_config)
111
+ error "Failed to copy launchd config file to #{LAUNCHD_CONFIG}" unless process_os_command "sudo cp #{temp_launchd_config} #{LAUNCHD_CONFIG}"
112
+ error "Failed to remove temporary launchd config file #{temp_launchd_config}" unless process_os_command "rm #{temp_launchd_config}"
113
+ display "Generating launchd config file '#{LAUNCHD_CONFIG}': OK"
114
+ end
115
+
116
+ unless launchd_service_loaded?
117
+ load_launchd_service
118
+ return
119
+ end
120
+
121
+ display "Astroboa service is already configured as a service. Use 'astroboa-cli service:check' to check the service status, use 'astroboa-cli service:start' and 'astroboa-cli service:stop' to start and stop astroboa service"
122
+ # FileUtils.mkdir_p log_dir, :mode => 0755 unless File.exists? log_dir
123
+ end
124
+
125
+ def load_launchd_service
126
+ error "Failed to load astroboa service to launchd" unless process_os_command "launchctl load #{LAUNCHD_CONFIG}"
127
+ display "Load astroboa service to launchd: OK"
128
+ display "Checking proper service load..."
129
+ error "Failed to load astroboa as a service" unless launchd_service_loaded?
130
+ display "astroboa service properly loaded: OK"
131
+ display "astroboa service is now starting...You can check the log file with 'tail -f #{log_file}'"
132
+ display "If you want to STOP THE SERVICE use 'astroboa-cli service:stop'. To START THE SERVICE again use 'astroboa-cli service:start'. "
133
+ display "ATTENTION!!! astroboa service will automatically start every time your MAC starts."
134
+ display "If you want to disable astroboa service from automatically running on each boot then change the 'RunAtLoad' key to false in '/Library/LaunchAgents/com.betaconcept.astroboa.plist'"
135
+ end
136
+
137
+ def launchd_service_configured?
138
+
139
+ unless File.exist?(LAUNCHD_CONFIG)
140
+ display "#{LAUNCHD_CONFIG} not installed"
141
+ return false
142
+ end
143
+
144
+ display "launchd config script '#{LAUNCHD_CONFIG}': OK"
145
+ return true
146
+ end
147
+
148
+
149
+ def launchd_service_loaded?
150
+ unless system 'launchctl list | grep astroboa'
151
+ display "Astroboa is not listed as a service in launchctl"
152
+ return false
153
+ end
154
+
155
+ display "launchctl lists astroboa as a service: OK"
156
+ return true
157
+ end
158
+
159
+
160
+ def check_launchd_service
161
+ display launchd_service_configured? ? "Astroboa is configured as a system service" :
162
+ "Astroboa is not configured as a service. Run 'astroboa-cli service:setup' to configure Astroboa as MAC OS X service"
163
+
164
+ display astroboa_running? ? 'Astroboa is running' : 'Astroboa is not running'
165
+ end
166
+
167
+
168
+ def start_launchd_service
169
+ unless launchd_service_configured?
170
+ output_with_bang "Astroboa is not yet setup as a system service. To setup up astroboa as a service use 'astroboa-cli service:setup'"
171
+ output_with_bang "If you just want to start astoboa without setting it up as a service use 'astroboa-cli server:start'"
172
+ exit
173
+ end
174
+
175
+ unless launchd_service_loaded?
176
+ display "astroboa service is not loaded lets loaded first"
177
+ load_launchd_service load_launchd_service
178
+
179
+ # we return since service automatically starts when loaded
180
+ return
181
+ end
182
+
183
+ error "Failed to start astroboa service" unless process_os_command "launchctl start com.betaconcept.astroboa"
184
+ display "Astroboa service has been started"
185
+ end
186
+
187
+
188
+ def stop_launchd_service
189
+ # To stop the service through launchd we need to use 'launchctl unload'
190
+ # we cannot use 'launchctl stop' because this will cause the service to be restarted again (this is due to keepalive settings in plist file)
191
+ # if we use 'launchctl unload' we need to reload the plist file each time we want to start astroboa again.
192
+ # To avoid all this we may stop astroboa directly through jboss-cli. This causes jboss to exit with status 0 and thus launchd does not restart it (see keepalive settings in plist file)
193
+ # So service:stop becomes equivalent to server:stop in MAC OS X.
194
+ # So even if astroboa is not a service we will stop it with service:stop but we do a check and inform the user to prefer server:stop if astroboa is not setup as a service
195
+
196
+ unless launchd_service_configured?
197
+ output_with_bang "We will try to stop astroboa but you should use this command to stop astroboa only if it is setup as a system service."
198
+ output_with_bang "Astroboa is not yet setup as a system service. To setup up astroboa as a service use 'astroboa-cli service:setup'"
199
+ output_with_bang "To stop astoboa when it is not setup as a service prefer to use 'astroboa-cli server:stop'"
200
+ end
201
+
202
+ AstroboaCLI::Command::Server.new().stop
203
+
204
+ end
205
+
206
+ def unset_launchd_service
207
+ display "Checking that astroboa is setup as a system service..."
208
+ error "Astroboa is not set as a system service" unless launchd_service_configured?
209
+
210
+ display "Checking that astroboa service is loaded..."
211
+ if launchd_service_loaded?
212
+ display "Trying to unload..."
213
+ error "Failed to unload astroboa service from launchd" unless process_os_command("launchctl unload #{LAUNCHD_CONFIG}") && ! launchd_service_loaded?
214
+ display "Astroboa service has been unloaded from launchd"
215
+ end
216
+
217
+ display 'Trying to remove from system services...'
218
+ error "Failed to remove launchd config file '#{LAUNCHD_CONFIG}'. Check that you have sudo permission and run the command again or manually remove the plist file." unless process_os_command "sudo rm #{LAUNCHD_CONFIG}"
219
+ display "Astroboa has been removed from system services"
220
+ end
221
+
222
+
223
+ end
224
+
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require "astroboa-cli/command/base"
4
+ require "astroboa-cli/version"
5
+
6
+ module AstroboaCLI::Command
7
+
8
+ # display version
9
+ #
10
+ class Version < Base
11
+
12
+ # version
13
+ #
14
+ # show astroboa client version
15
+ #
16
+ def default
17
+ display AstroboaCLI::VERSION
18
+ end
19
+ end # class Version
20
+
21
+ end # module AstroboaCLI::Command
@@ -0,0 +1,158 @@
1
+ # encoding: utf-8
2
+
3
+ # This file contains modifications of work covered by the following copyright and
4
+ # permission notice:
5
+ #
6
+ # The MIT License (MIT)
7
+ #
8
+ # Copyright © Heroku 2008 - 2012
9
+ #
10
+ # Permission is hereby granted, free of charge, to any person obtaining
11
+ # a copy of this software and associated documentation files (the
12
+ # "Software"), to deal in the Software without restriction, including
13
+ # without limitation the rights to use, copy, modify, merge, publish,
14
+ # distribute, sublicense, and/or sell copies of the Software, and to
15
+ # permit persons to whom the Software is furnished to do so, subject to
16
+ # the following conditions:
17
+ #
18
+ # The above copyright notice and this permission notice shall be
19
+ # included in all copies or substantial portions of the Software.
20
+ #
21
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
25
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
+
29
+ require "optparse"
30
+ require "astroboa-cli/util"
31
+
32
+ module AstroboaCLI
33
+ module Command
34
+
35
+ class CommandFailed < RuntimeError; end
36
+
37
+ extend AstroboaCLI::Util
38
+
39
+ def self.load
40
+ Dir[File.join(File.dirname(__FILE__), "command", "*.rb")].each do |file|
41
+ require file
42
+ end
43
+
44
+ @@log_file = '/tmp/astroboa-cli-log.txt'
45
+ f = File.new(@@log_file, 'w+', 0644)
46
+ @@log = Logger.new(f)
47
+ @@log.level = Logger::INFO
48
+ end
49
+
50
+ def self.log
51
+ @@log
52
+ end
53
+
54
+ def self.log_file
55
+ @@log_file
56
+ end
57
+
58
+ def self.namespaces
59
+ @@namespaces ||= {}
60
+ end
61
+
62
+ def self.commands
63
+ @@commands ||= {}
64
+ end
65
+
66
+ def self.current_command
67
+ @current_command
68
+ end
69
+
70
+ def self.current_args
71
+ @current_args
72
+ end
73
+
74
+ def self.current_options
75
+ @current_options
76
+ end
77
+
78
+ def self.global_options
79
+ @global_options ||= []
80
+ end
81
+
82
+ def self.global_option(name, *args)
83
+ global_options << { :name => name, :args => args }
84
+ end
85
+
86
+ global_option :help, "--help", "-h"
87
+
88
+ def self.register_command(command)
89
+ commands[command[:command]] = command
90
+ end
91
+
92
+ def self.register_namespace(namespace)
93
+ namespaces[namespace[:name]] = namespace
94
+ end
95
+
96
+ def self.map_command_to_method(cmd, args=[])
97
+ command = commands[cmd]
98
+
99
+ unless command
100
+ if %w( -v --version ).include?(cmd)
101
+ display AstroboaCLI::VERSION
102
+ exit
103
+ end
104
+
105
+ output_with_bang("`#{cmd}` is not an astroboa command.")
106
+
107
+ output_with_bang("run `astroboa-cli help` to see available commands.")
108
+ exit 1
109
+ end
110
+
111
+ @current_command = cmd
112
+
113
+ opts = {}
114
+ invalid_options = []
115
+
116
+ parser = OptionParser.new do |parser|
117
+ global_options.each do |global_option|
118
+ parser.on(*global_option[:args]) do |value|
119
+ opts[global_option[:name]] = value
120
+ end
121
+ end
122
+ command[:options].each do |name, option|
123
+ parser.on("-#{option[:short]}", "--#{option[:long]}", option[:desc]) do |value|
124
+ opts[name.gsub("-", "_").to_sym] = value
125
+ end
126
+ end
127
+ end
128
+
129
+ begin
130
+ parser.order!(args) do |nonopt|
131
+ invalid_options << nonopt
132
+ end
133
+ rescue OptionParser::InvalidOption => ex
134
+ invalid_options << ex.args.first
135
+ retry
136
+ end
137
+
138
+ raise OptionParser::ParseError if opts[:help]
139
+
140
+ args.concat(invalid_options)
141
+
142
+ @current_args = args
143
+ @current_options = opts
144
+
145
+ [ command[:klass].new(args.dup, opts.dup), command[:method] ]
146
+ end
147
+
148
+
149
+ def self.run(command, arguments=[])
150
+ object, method = map_command_to_method(command, arguments.dup)
151
+ object.send(method)
152
+ rescue => e
153
+ error "An error has occured \n#{e.inspect}\n#{e.backtrace}"
154
+ end
155
+
156
+ end # module Command
157
+ end # module AstroboaCLI
158
+
@@ -0,0 +1,594 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+ require 'zip/zip'
5
+ require 'nokogiri'
6
+
7
+ module AstroboaCLI
8
+ module Util
9
+
10
+ # This code is from Sprinkle that in turn got it from Chef !!
11
+ class TemplateError < RuntimeError
12
+ attr_reader :original_exception, :context
13
+ SOURCE_CONTEXT_WINDOW = 2 unless defined? SOURCE_CONTEXT_WINDOW
14
+
15
+ def initialize(original_exception, template, context)
16
+ @original_exception, @template, @context = original_exception, template, context
17
+ end
18
+
19
+ def message
20
+ @original_exception.message
21
+ end
22
+
23
+ def line_number
24
+ @line_number ||= $1.to_i if original_exception.backtrace.find {|line| line =~ /\(erubis\):(\d+)/ }
25
+ end
26
+
27
+ def source_location
28
+ "on line ##{line_number}"
29
+ end
30
+
31
+ def source_listing
32
+ return nil if line_number.nil?
33
+
34
+ @source_listing ||= begin
35
+ line_index = line_number - 1
36
+ beginning_line = line_index <= SOURCE_CONTEXT_WINDOW ? 0 : line_index - SOURCE_CONTEXT_WINDOW
37
+ source_size = SOURCE_CONTEXT_WINDOW * 2 + 1
38
+ lines = @template.split(/\n/)
39
+ contextual_lines = lines[beginning_line, source_size]
40
+ output = []
41
+ contextual_lines.each_with_index do |line, index|
42
+ line_number = (index+beginning_line+1).to_s.rjust(3)
43
+ output << "#{line_number}: #{line}"
44
+ end
45
+ output.join("\n")
46
+ end
47
+ end
48
+
49
+ def to_s
50
+ "\n\n#{self.class} (#{message}) #{source_location}:\n\n" +
51
+ "#{source_listing}\n\n #{original_exception.backtrace.join("\n ")}\n\n"
52
+ end
53
+ end
54
+
55
+
56
+ def display(msg="", new_line=true, add_to_log=true)
57
+ if new_line
58
+ puts(msg)
59
+ else
60
+ print(msg)
61
+ STDOUT.flush
62
+ end
63
+ log.info msg if add_to_log
64
+ end
65
+
66
+
67
+ def error(msg, add_to_log=true)
68
+ STDERR.puts(format_with_bang(msg))
69
+ log.error msg if add_to_log
70
+ exit 1
71
+ end
72
+
73
+
74
+ def fail(message)
75
+ raise AstroboaCLI::Command::CommandFailed, message
76
+ end
77
+
78
+
79
+ def format_with_bang(message)
80
+ return '' if message.to_s.strip == ""
81
+ " ! " + message.split("\n").join("\n ! ")
82
+ end
83
+
84
+
85
+ def output_with_bang(message="", new_line=true)
86
+ return if message.to_s.strip == ""
87
+ display(format_with_bang(message), new_line)
88
+ end
89
+
90
+
91
+ def ask
92
+ STDIN.gets.strip
93
+ end
94
+
95
+
96
+ def shell(cmd)
97
+ FileUtils.cd(Dir.pwd) {|d| return `#{cmd}`}
98
+ end
99
+
100
+
101
+ def longest(items)
102
+ items.map { |i| i.to_s.length }.sort.last
103
+ end
104
+
105
+
106
+ def has_executable(path)
107
+ # If the path includes a forward slash, we're checking
108
+ # an absolute path. Otherwise, we're checking a global executable
109
+ if path.include?('/')
110
+ commands = "test -x #{path}"
111
+ else
112
+ command = "[ -n \"`echo \\`which #{path}\\``\" ]"
113
+ end
114
+ process_os_command command
115
+ end
116
+
117
+
118
+ # Same as has_executable but with checking for e certain version number.
119
+ # If version number contains dots it, they should be escaped, e.g. "1\\.6"
120
+ # Last option is the parameter to append for getting the version (which
121
+ # defaults to "-v").
122
+ def has_executable_with_version(path, version, get_version = '-v')
123
+ if path.include?('/')
124
+ command = "[ -x #{path} -a -n \"`#{path} #{get_version} 2>&1 | egrep -e \\\"#{version}\\\"`\" ]"
125
+ else
126
+ command = "[ -n \"`echo \\`which #{path}\\``\" -a -n \"`\\`which #{path}\\` #{get_version} 2>&1 | egrep -e \\\"#{version}\\\"`\" ]"
127
+ end
128
+ process_os_command command
129
+ end
130
+
131
+
132
+ # Same as has_executable but checking output of a certain command
133
+ # with grep.
134
+ def has_version_in_grep(cmd, version)
135
+ process_os_command "[ -n \"`#{cmd} 2> /dev/null | egrep -e \\\"#{version}\\\"`\" ]"
136
+ end
137
+
138
+
139
+ def process_os_command(command)
140
+ system command
141
+ return false if $?.to_i != 0
142
+ return true
143
+ end
144
+
145
+
146
+ def extract_archive_command(archive_name)
147
+ case archive_name
148
+ when /(tar.gz)|(tgz)$/
149
+ 'tar xzf'
150
+ when /(tar.bz2)|(tb2)$/
151
+ 'tar xjf'
152
+ when /tar$/
153
+ 'tar xf'
154
+ when /zip$/
155
+ 'unzip -o -q'
156
+ else
157
+ fail "Unknown binary archive format: #{archive_name}"
158
+ end
159
+ end
160
+
161
+
162
+ def unzip_file (file, destination)
163
+ Zip::ZipFile.open(file) { |zip_file|
164
+ zip_file.each { |f|
165
+ next unless f.file?
166
+ f_path=File.join(destination, f.name)
167
+ FileUtils.mkdir_p(File.dirname(f_path))
168
+ zip_file.extract(f, f_path) unless File.exist?(f_path)
169
+ }
170
+ }
171
+ end
172
+
173
+
174
+ def render_template_to_file(template_path, context, file_path)
175
+ require 'erubis'
176
+
177
+ begin
178
+ template = File.read template_path
179
+ eruby = Erubis::Eruby.new(template)
180
+ File.open file_path, "w" do |f|
181
+ f << eruby.evaluate(context)
182
+ end
183
+ rescue Object => e
184
+ raise TemplateError.new(e, template, context)
185
+ end
186
+
187
+ end
188
+
189
+
190
+ # Delete file lines between two regular expressions, /foo/ and /bar/, including the lines
191
+ # that match the regular expressions, e.g. delete file lines between two comments, including the comments
192
+ # from_regex and to_regex should be specified without leading and trailing slashes i.e. "string_to_match" and not "/string_to_match/"
193
+ def delete_file_content_between_regex(filename, from_regex, to_regex)
194
+ from_regex_obj = %r{#{from_regex}}
195
+ to_regex_obj = %r{#{to_regex}}
196
+ found_boundary = false
197
+ file_lines = File.readlines(filename)
198
+ File.open(filename, "w") do |f|
199
+ file_lines.each do |line|
200
+ found_boundary = true if line =~ from_regex_obj
201
+ f.puts line unless found_boundary
202
+ found_boundary = false if line =~ to_regex_obj
203
+ end
204
+ end
205
+ end
206
+
207
+
208
+ def delete_file_lines(filename, lines_to_delete)
209
+ file_lines = File.readlines(filename)
210
+ lines_to_delete.each do |index|
211
+ file_lines.delete_at(index)
212
+ end
213
+ File.open(filename, "w") do |f|
214
+ f.write lines_to_delete.join
215
+ end
216
+ end
217
+
218
+
219
+ def windows?
220
+ RbConfig::CONFIG['host_os'] =~ /mswin/i
221
+ end
222
+
223
+
224
+ def mac_os_x?
225
+ RbConfig::CONFIG['host_os'] =~ /darwin/i
226
+ end
227
+
228
+
229
+ def linux?
230
+ RbConfig::CONFIG['host_os'] =~ /linux/i
231
+ end
232
+
233
+
234
+ def running_with_sudo?
235
+ Process.uid == 0
236
+ end
237
+
238
+
239
+ def check_if_running_with_sudo
240
+ display "You need sudo privileges to run this command. Checking..."
241
+ error <<-MSG.gsub(/^ {6}/, '') unless running_with_sudo?
242
+ You are not running with sudo privileges. Please run astroboa-cli with sudo
243
+ If you installed ruby with rbenv you need to install 'rbenv-sudo' plugin and then run 'rbenv sudo astroboa-cli <COMMAND>'
244
+ For 'rbenv-sudo' installation check ruby installation instructions at https://github.com/betaconcept/astroboa-cli
245
+ MSG
246
+
247
+ display "Running with sudo privileges: OK"
248
+ end
249
+
250
+
251
+ def dir_writable?(dir)
252
+ until FileTest.directory?(dir)
253
+ dir = File.dirname(dir)
254
+ end
255
+ File.writable? dir
256
+ end
257
+
258
+
259
+ def gem_available?(name)
260
+ Gem::Specification.find_by_name(name)
261
+ rescue Gem::LoadError
262
+ false
263
+ rescue
264
+ Gem.available?(name)
265
+ end
266
+
267
+
268
+ def astroboa_running?
269
+ server_config = get_server_configuration
270
+ jboss_dir = File.join(server_config['install_dir'], 'torquebox', 'jboss')
271
+ system %(ps -ef | grep "org.jboss.as.standalone -Djboss.home.dir=#{jboss_dir}" | grep -vq grep)
272
+ end
273
+
274
+
275
+ def get_server_conf_file
276
+ return File.expand_path(File.join("~", ".astroboa-conf.yml")) if mac_os_x?
277
+ return File.join(File::SEPARATOR, 'etc', 'astroboa', 'astroboa-conf.yml')
278
+ end
279
+
280
+
281
+ def save_server_configuration(server_configuration)
282
+ File.open(get_server_conf_file, "w") do |f|
283
+ f.write(YAML.dump(server_configuration))
284
+ end
285
+ end
286
+
287
+
288
+ def get_server_configuration
289
+ server_conf_file = get_server_conf_file
290
+ return YAML.load(File.read(server_conf_file)) if File.exists? server_conf_file
291
+ error "Server configuration file: '#{server_conf_file}' does not exist"
292
+ end
293
+
294
+
295
+ def repository_in_server_config?(server_config, repo_name)
296
+ return server_config.has_key?('repositories') && server_config['repositories'].has_key?(repo_name)
297
+ end
298
+
299
+
300
+ def repository_in_repos_config?(repos_dir, repository_name)
301
+ astroboa_repos_config = File.join(repos_dir, "repositories-conf.xml")
302
+
303
+ repo_conf = nil
304
+
305
+ if File.exists? astroboa_repos_config
306
+ File.open(astroboa_repos_config, 'r') do |f|
307
+ repo_conf = Nokogiri::XML(f) do |config|
308
+ config.noblanks
309
+ end
310
+ end
311
+
312
+ repo_nodes = repo_conf.xpath(%(//repository[@id="#{repository_name}"]))
313
+ return true if !repo_nodes.empty?
314
+ end
315
+
316
+ return false
317
+ end
318
+
319
+
320
+ # check that repo is consistently configured,
321
+ # i.e Its directory exists AND it is specified in server configuration AND its repo config file exists
322
+ def repository?(server_configuration, repository_name)
323
+ repos_dir = server_configuration['repos_dir']
324
+ astroboa_dir = server_configuration['install_dir']
325
+ repo_dir = File.join(repos_dir, repository_name)
326
+
327
+ return true if File.exists?(repo_dir) && repository_in_repos_config?(repos_dir, repository_name) && repository_in_server_config?(server_configuration, repository_name)
328
+
329
+ return false;
330
+ end
331
+
332
+
333
+ def runs_with_jruby?
334
+ (defined? RUBY_ENGINE && RUBY_ENGINE == 'jruby') || RUBY_PLATFORM == "java"
335
+ end
336
+
337
+
338
+ def jruby_version_ok?
339
+ return false unless defined? JRUBY_VERSION
340
+
341
+ jruby_version_numbers = JRUBY_VERSION.split(".")
342
+
343
+ return false unless jruby_version_numbers[0].to_i == 1 &&
344
+ ((jruby_version_numbers[1].to_i == 6 && jruby_version_numbers[2].to_i >= 7) || jruby_version_numbers[1].to_i == 7)
345
+ return true
346
+ end
347
+
348
+
349
+ def ruby_version_ok?
350
+ return false unless defined? RUBY_VERSION
351
+
352
+ ruby_version_numbers = RUBY_VERSION.split(".")
353
+
354
+ return false unless ruby_version_numbers[0].to_i == 1 && ruby_version_numbers[1].to_i >= 9
355
+ return true
356
+ end
357
+
358
+
359
+ def ruby_ok?
360
+ ruby_installation_instructions_message =<<-RUBY_INSTALL_MESSAGE
361
+ You can easily install ruby with 'rbenv' or 'rvm' utility programs.
362
+
363
+ ----------------------------------
364
+ We recommend to install ruby using the 'rbenv' and 'ruby-build' utility commands.
365
+ On Mac OS X to install 'rbenv' and 'ruby-build' using the Homebrew (http://mxcl.github.com/homebrew/) package manager do:
366
+ $ brew update
367
+ $ brew install rbenv
368
+ $ brew install ruby-build
369
+
370
+ To install ruby version 1.9.3-p194 do:
371
+ $ rbenv install 1.9.3-p194
372
+
373
+ To set the global version of Ruby to be used in all your shells do:
374
+ $ rbenv global 1.9.3-p194
375
+
376
+ To set ruby 1.9.3-p194 as a local per-project ruby version by writing the version name to an .rbenv-version file in the current directory do:
377
+
378
+ $ rbenv local 1.9.3-p194
379
+
380
+ To set ruby 1.9.3-p194 as the version to be used only in the current shell (sets the RBENV_VERSION environment variable in your shell) do:
381
+
382
+ $ rbenv shell 1.9.3-p194
383
+
384
+ -------------------------------
385
+ If you prefer to use 'rvm' as your ruby management utility use the following command to install it for a single user:
386
+
387
+ user$ curl -L get.rvm.io | bash -s stable
388
+
389
+ For multi-user installation and detailed rvm installation instructions check: https://rvm.io/rvm/install/
390
+
391
+ After 'rvm' has been installed run the following commands to install ruby 1.9.3-p194:
392
+ rvm install 1.9.3-p194
393
+ rvm use 1.9.3-p194
394
+ RUBY_INSTALL_MESSAGE
395
+
396
+ ruby_wrong_version_message =<<-RUBY_VERSION_MESSAGE
397
+ It seems that you are not running ruby 1.9.x.
398
+ Your current Ruby Version is: #{RUBY_VERSION}
399
+ Astroboa CLI requires your ruby version to be 1.9.x (e.g. 1.9.2 or 1.9.3).
400
+
401
+ #{ruby_installation_instructions_message}
402
+ RUBY_VERSION_MESSAGE
403
+
404
+ error ruby_wrong_version_message unless ruby_version_ok?
405
+ #display "Checking if your ruby version is 1.9.x: OK"
406
+ end
407
+
408
+
409
+ def jruby_ok?
410
+ install_jruby_with_rvm_message =<<-RVM_INSTALL_MESSAGE
411
+ We recommend to install jruby using the "RVM" utility command
412
+ To install "rvm" for a single user (i.e. the user that will run astroboa-cli) login as the user and run the following command:
413
+
414
+ user$ curl -L get.rvm.io | bash -s stable
415
+
416
+ For multi-user installation and detailed rvm installation instructions check: https://rvm.io/rvm/install/
417
+
418
+ After RVM has been installed run the following commands to install jruby:
419
+ rvm install jruby-1.6.7
420
+ rvm use jruby-1.6.7
421
+ RVM_INSTALL_MESSAGE
422
+
423
+ jruby_not_running_message =<<-JRUBY_MESSAGE
424
+ It seems that you are not running jruby.
425
+ Astroboa requires jruby version 1.6.7 or above.
426
+ Please install jruby version 1.6.7 or above and run the astroboa-cli command again
427
+
428
+ #{install_jruby_with_rvm_message}
429
+ JRUBY_MESSAGE
430
+
431
+ jruby_wrong_version_message =<<-JRUBY_VERSION_MESSAGE
432
+ It seems that you are not running the required jruby version
433
+ Your jruby version is: #{JRUBY_VERSION}
434
+ Astroboa requires jruby version 1.6.7 or above.
435
+ Please install jruby version 1.6.7 or above and run the astroboa-cli command again
436
+
437
+ #{install_jruby_with_rvm_message}
438
+ JRUBY_VERSION_MESSAGE
439
+
440
+ ruby_wrong_version_message =<<-RUBY_VERSION_MESSAGE
441
+ It seems that you are not running jruby in 1.9 mode.
442
+ Your current Ruby Version is: #{RUBY_VERSION}
443
+ Astroboa requires your jruby to run in 1.9 mode.
444
+ To make jruby run in 1.9 mode add the following to your .bash_profile
445
+ export JRUBY_OPTS=--1.9
446
+
447
+ You need to logout and login or run "source ~/.bash_profile" in order to activate this setting
448
+ RUBY_VERSION_MESSAGE
449
+
450
+ error jruby_not_running_message unless runs_with_jruby?
451
+ error jruby_wrong_version_message unless jruby_version_ok?
452
+ error ruby_wrong_version_message unless ruby_version_ok?
453
+ display "Checking if you are running jruby version 1.6.7 or above in 1.9 mode: OK"
454
+ end
455
+
456
+
457
+ def get_postgresql_config(server_configuration)
458
+ database_admin = server_configuration['database_admin']
459
+ database_admin_password = server_configuration['database_admin_password']
460
+ database_server = server_configuration['database_server']
461
+ return database_admin, database_admin_password, database_server
462
+ end
463
+
464
+
465
+ def create_postgresql_db(server_configuration, database_name)
466
+ database_admin, database_admin_password, database_server = get_postgresql_config(server_configuration)
467
+ begin
468
+ conn = PG.connect(
469
+ :host => database_server,
470
+ :port => '5432',
471
+ :dbname => 'postgres',
472
+ :user => database_admin,
473
+ :password => database_admin_password)
474
+
475
+ # check if db exists
476
+ res = conn.exec("SELECT COUNT(*) FROM pg_database WHERE datname=$1",[database_name])
477
+ unless res.entries[0]['count'] == 0
478
+ display "Database #{database_name} exists. You may run the command with --db_name repo_db_name to specify a different database name"
479
+ raise
480
+ end
481
+
482
+ res = conn.exec("CREATE DATABASE $1 ENCODING 'UNICODE'", [database_name])
483
+ if res.result_status == PG::Result::PGRES_COMMAND_OK
484
+ display %(Create Postges database "#{database_name}" : OK)
485
+ else
486
+ display "Failed to create postgres database #{database_name}. The error is #{res.error_message}"
487
+ raise
488
+ end
489
+ rescue PG::Error => e
490
+ display %(An error has occured during the creation of postgres database "#{database_name}")
491
+ display "The error is: #{res.error_message}"
492
+ display %(The error trace is \n #{e.backtrace.join("\n")})
493
+ raise
494
+ else
495
+ display %(An error has occured during the creation of postgres database "#{database_name}")
496
+ display %(The error trace is \n #{e.backtrace.join("\n")})
497
+ ensure
498
+ conn.finish if conn && !conn.finished?
499
+ end
500
+ end
501
+
502
+
503
+ def drop_postgresql_db(server_configuration, database_name)
504
+ database_admin, database_admin_password, database_server = get_postgresql_config(server_configuration)
505
+ begin
506
+ conn = PG.connect(
507
+ :host => database_server,
508
+ :port => '5432',
509
+ :dbname => 'postgres',
510
+ :user => database_admin,
511
+ :password => database_admin_password)
512
+
513
+ # check if db exists
514
+ res = conn.exec("SELECT COUNT(*) FROM pg_database WHERE datname=$1",[database_name])
515
+ unless res.entries[0]['count'] == 0
516
+ display "Cannot remove database #{database_name} because it does not exist"
517
+ raise
518
+ end
519
+
520
+ res = conn.exec("DROP DATABASE $1", [database_name])
521
+ if res.result_status == PG::Result::PGRES_COMMAND_OK
522
+ display %(Delete Postges database "#{database_name}" : OK)
523
+ else
524
+ display "Failed to delete postgres database #{database_name}. The error is #{res.error_message}"
525
+ raise
526
+ end
527
+
528
+ rescue PG::Error => e
529
+ display %(An error has occured during the deletion of postgres database "#{database_name}")
530
+ display "The error is: #{res.error_message}"
531
+ display %(The error trace is \n #{e.backtrace.join("\n")})
532
+ raise
533
+ else
534
+ display %(An error has occured during the deletion of postgres database "#{database_name}")
535
+ display %(The error trace is \n #{e.backtrace.join("\n")})
536
+ ensure
537
+ conn.finish if conn && !conn.finished?
538
+ end
539
+ end
540
+
541
+
542
+ # Not used because only works in jruby, TO BE REMOVED
543
+ def create_postgresql_db_with_jdbc(server_configuration, database_name, repo_dir)
544
+ database_admin, database_admin_password, database_server = get_postgresql_config(server_configuration)
545
+ begin
546
+ ActiveRecord::Base.establish_connection(
547
+ :adapter => 'jdbcpostgresql',
548
+ :database => "postgres",
549
+ :username => database_admin,
550
+ :password => database_admin_password,
551
+ :host => database_server,
552
+ :port => 5432)
553
+ ActiveRecord::Base.connection.create_database database_name, :encoding => 'unicode'
554
+ ActiveRecord::Base.connection.disconnect!
555
+ ActiveRecord::Base.remove_connection
556
+
557
+ display %(Create Postges database "#{database_name}" : OK)
558
+ rescue ActiveRecord::StatementInvalid => e
559
+ if e.message =~ /database "#{database_name}" already exists/
560
+ display "Database #{database_name} exists. You may run the command with --db_name repo_db_name to specify a different database name"
561
+ else
562
+ display %(An error has occured during the creation of postgres database "#{database_name}")
563
+ display %(The error trace is \n #{e.backtrace.join("\n")})
564
+ end
565
+
566
+ raise
567
+ end
568
+ end
569
+
570
+
571
+ # Not used because only works in jruby, TO BE REMOVED
572
+ def drop_postgresql_db_with_jdbc(server_configuration, database_name)
573
+ database_admin, database_admin_password, database_server = get_postgresql_config(server_configuration)
574
+ begin
575
+ ActiveRecord::Base.establish_connection(
576
+ :adapter => 'jdbcpostgresql',
577
+ :database => "postgres",
578
+ :username => database_admin,
579
+ :password => database_admin_password,
580
+ :host => database_server,
581
+ :port => 5432)
582
+ ActiveRecord::Base.connection.drop_database database_name
583
+ ActiveRecord::Base.connection.disconnect!
584
+ ActiveRecord::Base.remove_connection
585
+
586
+ display %(Delete Postges database "#{database_name}" : OK)
587
+ rescue ActiveRecord::StatementInvalid => e
588
+ display %(An error has occured during the deletion of postgres database "#{database_name}")
589
+ display %(The error trace is \n #{e.backtrace.join("\n")})
590
+ raise
591
+ end
592
+ end
593
+ end
594
+ end