Last active
October 2, 2015 01:58
-
-
Save manchunlam/2149277 to your computer and use it in GitHub Desktop.
Script for Common Scalr Tasks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'getoptlong' | |
KNIFE_SSH_OPT = '-x deploy -i ~/.ssh/id_rsa -a ec2.public_hostname' | |
VERSION = "1.1.0" | |
@project = "" | |
@env = "staging" | |
@instance_type = "" | |
@error_only = true | |
# Help onto stdout | |
def print_usage | |
usage = <<-END_USAGE.gsub(/^( {4})/, '') | |
scalr is a tool to perform common tasks for projects hosted in Scalr | |
Usage: | |
scalr [options] [instance_type] | |
where [options] are: | |
--project, -p <s>: Project name | |
--env, -e <s>: Set <environment>, defaults to "staging" if switch is not present | |
--tail, -t: Tail <environment>.log | |
--util-services: See running services on utility servers | |
--deploy: Deploy project to <environment> | |
--deployed-version: Check SHA of code-base in <environment> | |
--node-list: List node names and instance-roles | |
--version, -v: Print version | |
--help, -h: Show this message | |
where [instance_type] is: | |
--all: (default) run command on all servers | |
--app-servers: run command on Application Servers | |
--utilities: run command on Utility Servers | |
END_USAGE | |
example = <<-END_EXAMPLE.gsub(/^( {4})/, '') | |
Example: | |
To deploy: ./scalr.rb --project tabs --deploy | |
To tail log on staging: ./scalr.rb --project tabs --tail | |
To see deployed code version: ./scalr.rb --project --deployed-version | |
To change target environment to production: ./scalr.rb --project tabs --env production --tail | |
END_EXAMPLE | |
puts usage | |
puts example | |
end | |
# Build knife search_query string | |
def knife_ssh_query(type='all') | |
base = "knife ssh 'applications:#{@project} AND app_environment:#{@env}'" | |
case type | |
when '', 'all' | |
base.gsub(/'$/, " AND ( instance_role:ap* OR instance_role:uti* )'") | |
when 'app-servers' | |
base.gsub(/'$/, " AND instance_role:ap*'") | |
when 'utilities' | |
base.gsub(/'$/, " AND instance_role:uti*'") | |
end | |
end | |
# Build complete shell command string | |
def knife_ssh(ssh_cmd) | |
"#{knife_ssh_query(@instance_type)} '#{ssh_cmd}' #{KNIFE_SSH_OPT}" | |
end | |
opts = GetoptLong.new( | |
[ '--app-servers', GetoptLong::NO_ARGUMENT ], | |
[ '--utilities', GetoptLong::NO_ARGUMENT ], | |
[ '--all', GetoptLong::NO_ARGUMENT ], | |
[ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ], | |
[ '--env', '-e', GetoptLong::OPTIONAL_ARGUMENT ], | |
[ '--tail', '-t', GetoptLong::NO_ARGUMENT ], | |
[ '--util-services', GetoptLong::NO_ARGUMENT ], | |
[ '--deploy', GetoptLong::NO_ARGUMENT ], | |
[ '--deployed-version', GetoptLong::NO_ARGUMENT ], | |
[ '--version', '-v', GetoptLong::NO_ARGUMENT ], | |
[ '--help', '-h', GetoptLong::NO_ARGUMENT ], | |
[ '--show-all', GetoptLong::NO_ARGUMENT ], | |
[ '--node-list', GetoptLong::NO_ARGUMENT ] | |
) | |
# Output command result to stdout | |
def show_line(line, regex=nil, keys_to_print=[]) | |
unless regex | |
puts line | |
else | |
matched = regex.match(line) | |
if matched | |
if keys_to_print.empty? | |
puts line | |
else | |
if ( matched.names & keys_to_print ) == keys_to_print | |
output = "" | |
keys_to_print.map {|k| | |
output << "#{matched[k]} " | |
} | |
puts output | |
end | |
end | |
end | |
end | |
end | |
# Execute the command | |
def tail_command(command, regex=nil, keys_to_print=[]) | |
begin | |
IO.popen(command) do |f| | |
while line = f.gets | |
show_line(line, regex, keys_to_print) | |
end | |
end | |
rescue => e | |
puts e.inspect | |
rescue SignalException | |
puts 'Execution halted by user' | |
end | |
end | |
# Generate log-tailing command string | |
def tail_log | |
ssh_cmd = "tail -n 100 -f /data/#{@project}/current/log/#{@env}.log" | |
knife_ssh(ssh_cmd) | |
end | |
# Generate project-deployment command string | |
def deploy | |
ssh_cmd = 'sudo chef-client -j /etc/chef/chef.default.json' | |
knife_ssh(ssh_cmd) | |
end | |
# Prompt to deploy confirmation | |
def deploy_prompt | |
message = <<-END_MSG.gsub(/^( {4})/, '') | |
You are about to deploy, please confirm the following params: | |
project: #{@project} | |
env: #{@env} | |
command: #{@shell_cmd} | |
Do you want to deploy? (y|n) | |
END_MSG | |
puts message | |
confirmed = gets.chomp.downcase | |
%w(y yes).include?(confirmed) | |
end | |
# Generate version-check command string | |
def check_version | |
ssh_cmd = "cd /data/#{@project} && ls -al" | |
knife_ssh(ssh_cmd) | |
end | |
# Generate show-util-services command string | |
def see_util_services | |
ssh_cmd = 'sudo monit summary' | |
knife_ssh(ssh_cmd) | |
end | |
# Generate show-hostname command string | |
def show_hostname | |
ssh_cmd = 'hostname' | |
knife_ssh(ssh_cmd) | |
end | |
# Error regex | |
def error_regex | |
if @error_only | |
/role\[staging\]|error/i | |
else | |
nil | |
end | |
end | |
# Check if `knife` exists | |
def knife_installed? | |
`which knife` | |
$?.success? | |
end | |
# Prompt for knife installation | |
def install_knife_msg | |
message = <<-END_MSG.gsub(/^( {4})/, '') | |
`knife` command is not found. It is a dependency for this script. | |
Please install it by `gem install chef` | |
END_MSG | |
puts message | |
end | |
begin | |
if ARGV.length == 0 | |
print_usage | |
opts.terminate | |
end | |
unless knife_installed? | |
install_knife_msg | |
opts.terminate | |
end | |
@func = '' | |
opts.each do |opt, arg| | |
case opt | |
when '--project' | |
@project = arg | |
when "--env" | |
if arg != '' | |
@env = arg | |
end | |
when '--tail' | |
@func = 'tail_log' | |
when "--util-services" | |
@func = 'see_util_services' | |
when "--deploy" | |
@func = 'deploy' | |
when "--deployed-version" | |
@func = 'check_version' | |
when '--node-list' | |
@func = 'show_hostname' | |
when '--all' | |
@instance_type = 'all' | |
when '--app-servers' | |
@instance_type = 'app-servers' | |
when '--utilities' | |
@instance_type = 'utilities' | |
when '--show-all' | |
@error_only = false | |
when "--version" | |
puts VERSION | |
when "--help" | |
print_usage | |
end | |
end | |
if @shell_cmd = eval(@func) | |
case @func | |
when 'deploy' | |
tail_command(@shell_cmd, error_regex) if deploy_prompt | |
when 'check_version' | |
version_regex = /(?<machine>.*\.amazonaws\.com).*current.*releases\/(?<sha>[a-zA-Z0-9]*)/ | |
tail_command(@shell_cmd, version_regex, ["machine", "sha"]) | |
else | |
tail_command(@shell_cmd) | |
end | |
end | |
rescue => e | |
puts e.inspect | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
check_version
returns SHA for both app and util servers.