appli 0.0.12 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/appli/deploy.rb +144 -0
- metadata +26 -56
- data/bin/appli +0 -3
- data/lib/appli/command.rb +0 -144
- data/lib/appli.rb +0 -181
- data/lib/commands/apps.rb +0 -55
- data/lib/commands/cap.rb +0 -30
- data/lib/commands/db.rb +0 -82
- data/lib/commands/domains.rb +0 -40
- data/lib/commands/gems.rb +0 -58
- data/lib/commands/keys.rb +0 -14
- data/lib/commands/logs.rb +0 -6
- data/lib/commands/ssh.rb +0 -5
- data/lib/commands/stats.rb +0 -26
data/lib/appli/deploy.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
default_run_options[:pty] = true
|
4
|
+
|
5
|
+
## Define the default roles
|
6
|
+
role :app
|
7
|
+
|
8
|
+
## Set the default configuration
|
9
|
+
set :user, "deploy"
|
10
|
+
set :ssh_options, {:forward_agent => true, :port => 22}
|
11
|
+
set :environment, "production"
|
12
|
+
set :branch, "master"
|
13
|
+
|
14
|
+
namespace :setup do
|
15
|
+
|
16
|
+
desc 'Initialises the application on your server(s)'
|
17
|
+
task :default do
|
18
|
+
|
19
|
+
unless ENV['DBPASS']
|
20
|
+
puts "\n \e[31mAn error occurred while setting up your remote repository:\n\n"
|
21
|
+
puts " You must pass DBPASS to this task. This should be the database password for the database"
|
22
|
+
puts " with the name '#{database_user}' on #{database_host}.\e[0m\n\n"
|
23
|
+
|
24
|
+
next
|
25
|
+
end
|
26
|
+
|
27
|
+
## Clear anything out the way of the application
|
28
|
+
run "rm -Rf #{deploy_to}"
|
29
|
+
|
30
|
+
## Clone the repository into the folder
|
31
|
+
run "git clone -n #{repository} #{deploy_to} --branch #{branch} --quiet"
|
32
|
+
|
33
|
+
## Create a rollback branch, create a new branch called 'deploy' and remove the
|
34
|
+
## origin branch
|
35
|
+
run "cd #{deploy_to} && git branch rollback && git checkout -b deploy && git branch -d #{branch}"
|
36
|
+
|
37
|
+
## Upload the database configuration
|
38
|
+
add_db_config
|
39
|
+
|
40
|
+
## Finalize
|
41
|
+
deploy.finalise
|
42
|
+
end
|
43
|
+
|
44
|
+
desc 'Initialises the application (including the database schema)'
|
45
|
+
task :full do
|
46
|
+
puts
|
47
|
+
puts " \e[36mPotentially dangerous action - read this carefully:\e[0m"
|
48
|
+
puts " This task will clear your database (#{database_name}) when it has completed setting"
|
49
|
+
puts " up the remote repository. We will wait 15 seconds for you to change your mind. Press"
|
50
|
+
puts " CTRL+C to cancel this task now."
|
51
|
+
puts
|
52
|
+
sleep 15
|
53
|
+
|
54
|
+
default
|
55
|
+
load_schema
|
56
|
+
deploy.start
|
57
|
+
|
58
|
+
puts
|
59
|
+
puts " \e[32mYour application has now been set up for the first time\e[0m"
|
60
|
+
puts
|
61
|
+
end
|
62
|
+
|
63
|
+
desc 'Upload a database configuration using the variables you enter'
|
64
|
+
task :add_db_config, :roles => [:app] do
|
65
|
+
next unless fetch(:database_host, nil)
|
66
|
+
configuration = Array.new.tap do |a|
|
67
|
+
a << "#{environment}:"
|
68
|
+
a << " adapter: mysql2"
|
69
|
+
a << " encoding: utf8"
|
70
|
+
a << " reconnect: true"
|
71
|
+
a << " host: #{database_host}"
|
72
|
+
a << " database: #{database_name}"
|
73
|
+
a << " username: #{database_user}"
|
74
|
+
a << " password: #{ENV['DBPASS'] || 'xxxxx'}"
|
75
|
+
a << " pool: 5\n"
|
76
|
+
end.join("\n")
|
77
|
+
put configuration, "#{deploy_to}/config/database.yml"
|
78
|
+
end
|
79
|
+
|
80
|
+
desc 'Load the schema'
|
81
|
+
task :load_schema, :roles => [:app], :only => {:database_ops => true} do
|
82
|
+
run "cd #{deploy_to} && RAILS_ENV=#{environment} bundle exec rake db:schema:load"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
namespace :deploy do
|
87
|
+
desc 'Deploy your application'
|
88
|
+
task :default do
|
89
|
+
update_code
|
90
|
+
restart
|
91
|
+
end
|
92
|
+
|
93
|
+
desc 'Deploy and run migrations'
|
94
|
+
task :migrations do
|
95
|
+
set :run_migrations, true
|
96
|
+
default
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
task :update_code do
|
101
|
+
run "cd #{deploy_to} && git branch -d rollback && git branch rollback"
|
102
|
+
run "cd #{deploy_to} && git fetch origin && git reset --hard origin/#{fetch(:branch)}"
|
103
|
+
finalise
|
104
|
+
end
|
105
|
+
|
106
|
+
task :finalise do
|
107
|
+
execute = Array.new
|
108
|
+
execute << "cd #{deploy_to}"
|
109
|
+
execute << "git submodule init"
|
110
|
+
execute << "git submodule sync"
|
111
|
+
execute << "git submodule update --recursive"
|
112
|
+
run execute.join(' && ')
|
113
|
+
|
114
|
+
run "cd #{deploy_to} && bundle --deployment --quiet"
|
115
|
+
assets
|
116
|
+
migrate if fetch(:run_migrations, false)
|
117
|
+
end
|
118
|
+
|
119
|
+
desc 'Run any database migrations'
|
120
|
+
task :migrate, :roles => [:app], :only => {:database_ops => true} do
|
121
|
+
run "cd #{deploy_to} && RAILS_ENV=#{environment} bundle exec rake db:migrate"
|
122
|
+
end
|
123
|
+
|
124
|
+
task :assets, :roles => [:app] do
|
125
|
+
run "if [ -e #{deploy_to}/app/assets ] ; then cd #{deploy_to} && RAILS_ENV=#{environment} bundle exec rake assets:precompile ; fi"
|
126
|
+
end
|
127
|
+
|
128
|
+
desc 'Reset the application'
|
129
|
+
task :restart, :roles => [:app] do
|
130
|
+
run "mkdir -p #{deploy_to}/tmp && touch #{deploy_to}/restart.txt"
|
131
|
+
end
|
132
|
+
|
133
|
+
desc 'Start the application'
|
134
|
+
task :start, :roles => [:app] do
|
135
|
+
restart
|
136
|
+
end
|
137
|
+
|
138
|
+
desc 'Stop the application'
|
139
|
+
task :stop, :roles => [:app] do
|
140
|
+
restart
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
metadata
CHANGED
@@ -1,75 +1,45 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: appli
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
+
authors:
|
7
8
|
- Adam Cooke
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
default_executable:
|
14
|
-
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: json
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 1.1.5
|
24
|
-
version:
|
12
|
+
date: 2011-12-10 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
25
14
|
description:
|
26
15
|
email: adam@atechmedia.com
|
27
|
-
executables:
|
28
|
-
- appli
|
16
|
+
executables: []
|
29
17
|
extensions: []
|
30
|
-
|
31
18
|
extra_rdoc_files: []
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
- lib/appli/command.rb
|
36
|
-
- lib/appli.rb
|
37
|
-
- lib/commands/apps.rb
|
38
|
-
- lib/commands/cap.rb
|
39
|
-
- lib/commands/db.rb
|
40
|
-
- lib/commands/domains.rb
|
41
|
-
- lib/commands/gems.rb
|
42
|
-
- lib/commands/keys.rb
|
43
|
-
- lib/commands/logs.rb
|
44
|
-
- lib/commands/ssh.rb
|
45
|
-
- lib/commands/stats.rb
|
46
|
-
has_rdoc: true
|
47
|
-
homepage: http://www.atechmedia.com
|
19
|
+
files:
|
20
|
+
- lib/appli/deploy.rb
|
21
|
+
homepage: http://www.applihq.com
|
48
22
|
licenses: []
|
49
|
-
|
50
23
|
post_install_message:
|
51
24
|
rdoc_options: []
|
52
|
-
|
53
|
-
require_paths:
|
25
|
+
require_paths:
|
54
26
|
- lib
|
55
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
27
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
67
39
|
requirements: []
|
68
|
-
|
69
40
|
rubyforge_project:
|
70
|
-
rubygems_version: 1.
|
41
|
+
rubygems_version: 1.8.10
|
71
42
|
signing_key:
|
72
43
|
specification_version: 3
|
73
|
-
summary:
|
44
|
+
summary: Deployment Recipes for Appli
|
74
45
|
test_files: []
|
75
|
-
|
data/bin/appli
DELETED
data/lib/appli/command.rb
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
module Appli
|
2
|
-
class Command
|
3
|
-
|
4
|
-
def initialize(block)
|
5
|
-
(class << self;self end).send :define_method, :command, &block
|
6
|
-
end
|
7
|
-
|
8
|
-
def debug?
|
9
|
-
false
|
10
|
-
end
|
11
|
-
|
12
|
-
def call(options, *args)
|
13
|
-
@options = options
|
14
|
-
arity = method(:command).arity
|
15
|
-
args << nil while args.size < arity
|
16
|
-
send :command, *args
|
17
|
-
rescue Error => e
|
18
|
-
puts "An error occured while excuting your command...\n#{e.message}"
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def host
|
24
|
-
application['host']
|
25
|
-
end
|
26
|
-
|
27
|
-
def application
|
28
|
-
return nil if @options[:application].nil?
|
29
|
-
@application ||= get("applications/#{@options[:application]}")['application']
|
30
|
-
rescue
|
31
|
-
puts "Application not found with identifier '#{@options[:application]}'"
|
32
|
-
Process.exit(1)
|
33
|
-
end
|
34
|
-
|
35
|
-
def options
|
36
|
-
@options || Hash.new
|
37
|
-
end
|
38
|
-
|
39
|
-
def git_config_variable(name)
|
40
|
-
@config_variables = Hash.new if @config_variables.nil?
|
41
|
-
if @config_variables[name]
|
42
|
-
@config_variables[name]
|
43
|
-
else
|
44
|
-
r = `git config appli.#{name.to_s}`.chomp
|
45
|
-
puts "Getting configuration variable: appli.#{name.to_s} (was: '#{r}')" if debug?
|
46
|
-
@config_variables[name] = (r.empty? ? nil : r)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def api_request(url, username, password, data = nil, method = nil)
|
51
|
-
require 'uri'
|
52
|
-
require 'net/http'
|
53
|
-
require 'net/https'
|
54
|
-
uri = URI.parse(url)
|
55
|
-
|
56
|
-
if method.nil?
|
57
|
-
method = (data ? :post : :get)
|
58
|
-
end
|
59
|
-
|
60
|
-
req = case method
|
61
|
-
when :post
|
62
|
-
Net::HTTP::Post.new(uri.path)
|
63
|
-
when :delete
|
64
|
-
Net::HTTP::Delete.new(uri.path)
|
65
|
-
when :put
|
66
|
-
Net::HTTP::Put.new(uri.path)
|
67
|
-
else
|
68
|
-
Net::HTTP::Get.new(uri.path)
|
69
|
-
end
|
70
|
-
|
71
|
-
req.basic_auth(username, password)
|
72
|
-
req.add_field("Accept", "application/json")
|
73
|
-
req.add_field("Content-type", "application/json")
|
74
|
-
res = Net::HTTP.new(uri.host, uri.port)
|
75
|
-
if url.include?('https://')
|
76
|
-
res.use_ssl = true
|
77
|
-
res.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
78
|
-
end
|
79
|
-
puts "Requesting '#{url}' on as #{method.to_s.upcase}" if debug?
|
80
|
-
res = res.request(req, data)
|
81
|
-
case res
|
82
|
-
when Net::HTTPSuccess
|
83
|
-
return res.body
|
84
|
-
when Net::HTTPNotFound
|
85
|
-
puts "Resource not found"
|
86
|
-
Process.exit(1)
|
87
|
-
when Net::HTTPServiceUnavailable
|
88
|
-
puts "The API is currently unavailable. Please check your codebase account has been enabled for API access."
|
89
|
-
Process.exit(1)
|
90
|
-
when Net::HTTPForbidden, Net::HTTPUnauthorized, Net::HTTPFound
|
91
|
-
puts "\e[41;37mAccess Denied. Check your appli username & API key have been configured correctly.\e[0m"
|
92
|
-
Process.exit(1)
|
93
|
-
else
|
94
|
-
@errors = res.body
|
95
|
-
return false
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def errors
|
100
|
-
@errors || nil
|
101
|
-
end
|
102
|
-
|
103
|
-
def get(path)
|
104
|
-
JSON.parse(api(path))
|
105
|
-
end
|
106
|
-
|
107
|
-
def api(path, data = nil, method = nil)
|
108
|
-
api_request("http://#{domain}/#{path}", git_config_variable(:username), git_config_variable(:apikey), data, method)
|
109
|
-
end
|
110
|
-
|
111
|
-
def api_on_app(path, data = nil, method = nil)
|
112
|
-
api("applications/#{@options[:application]}/#{path}", data, method)
|
113
|
-
end
|
114
|
-
|
115
|
-
def domain
|
116
|
-
git_config_variable(:domain) || 'applihq.com'
|
117
|
-
end
|
118
|
-
|
119
|
-
def ssh(command, filter = //)
|
120
|
-
puts remote_exec(command).gsub(filter, '')
|
121
|
-
end
|
122
|
-
|
123
|
-
def remote_exec(command)
|
124
|
-
command = "ssh -p #{application['ssh_port']} app@#{host['name']} \"#{command}\""
|
125
|
-
puts "Executing: #{command}" if debug?
|
126
|
-
`#{command}`
|
127
|
-
end
|
128
|
-
|
129
|
-
def ssh_exec(command)
|
130
|
-
exec("ssh -p #{application['ssh_port']} app@#{host['name']} \"#{command}\"")
|
131
|
-
end
|
132
|
-
|
133
|
-
def error(command, exit_code = 1)
|
134
|
-
$stderr.puts command
|
135
|
-
Process.exit(exit_code)
|
136
|
-
end
|
137
|
-
|
138
|
-
def display_errors
|
139
|
-
for key, value in JSON.parse(errors)
|
140
|
-
puts " * #{key.capitalize} #{value}"
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
data/lib/appli.rb
DELETED
@@ -1,181 +0,0 @@
|
|
1
|
-
$:.unshift File.dirname(__FILE__)
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'json'
|
5
|
-
|
6
|
-
require 'appli/command'
|
7
|
-
|
8
|
-
trap("INT") { puts; exit }
|
9
|
-
|
10
|
-
module Appli
|
11
|
-
extend self
|
12
|
-
|
13
|
-
class Error < RuntimeError; end
|
14
|
-
class NotConfiguredError < StandardError; end
|
15
|
-
class MustBeInRepositoryError < StandardError; end
|
16
|
-
|
17
|
-
VERSION = "0.0.12"
|
18
|
-
|
19
|
-
def run(command, args = [])
|
20
|
-
load_commands
|
21
|
-
command = 'help' if command.nil?
|
22
|
-
|
23
|
-
if @global_commands[command]
|
24
|
-
run_command(command, :global, args)
|
25
|
-
elsif @application_commands[args.first]
|
26
|
-
run_command(args.shift, :app, ([command] + args))
|
27
|
-
else
|
28
|
-
puts "usage: appli [command]"
|
29
|
-
puts "Command not found. Check 'appli help' for full information."
|
30
|
-
Process.exit(1)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def run_command(command, type, args = [])
|
35
|
-
array = (type == :global ? @global_commands : @application_commands)
|
36
|
-
|
37
|
-
options = parse_options(args)
|
38
|
-
options.merge!({:application => args.shift}) if type == :app
|
39
|
-
|
40
|
-
if args.size < array[command][:required_args].to_i
|
41
|
-
puts "error: #{array[command][:usage]}"
|
42
|
-
puts "See 'cb help #{command}' for usage."
|
43
|
-
Process.exit(1)
|
44
|
-
end
|
45
|
-
|
46
|
-
array[command][:block].call(options, *args)
|
47
|
-
end
|
48
|
-
|
49
|
-
def command(command, options = {}, &block)
|
50
|
-
hash = Hash.new
|
51
|
-
hash[:description] = @next_description
|
52
|
-
hash[:usage] = @next_usage
|
53
|
-
hash[:flags] = @next_flags
|
54
|
-
hash[:required_args] = (options[:required_args] || 0)
|
55
|
-
hash[:block] = Command.new(block)
|
56
|
-
|
57
|
-
@global_commands = Hash.new if @global_commands.nil?
|
58
|
-
@application_commands = Hash.new if @application_commands.nil?
|
59
|
-
|
60
|
-
if options[:global]
|
61
|
-
@global_commands[command] = hash
|
62
|
-
else
|
63
|
-
@application_commands[command] = hash
|
64
|
-
end
|
65
|
-
|
66
|
-
@next_usage, @next_description, @next_flags = nil, nil, nil
|
67
|
-
end
|
68
|
-
|
69
|
-
def global_commands
|
70
|
-
@global_commands
|
71
|
-
end
|
72
|
-
|
73
|
-
def application_commands
|
74
|
-
@application_commands
|
75
|
-
end
|
76
|
-
|
77
|
-
def commands
|
78
|
-
global_commands.merge(application_commands)
|
79
|
-
end
|
80
|
-
|
81
|
-
def desc(value)
|
82
|
-
@next_description = Array.new if @next_description.nil?
|
83
|
-
@next_description << value
|
84
|
-
end
|
85
|
-
|
86
|
-
def usage(value)
|
87
|
-
@next_usage = value
|
88
|
-
end
|
89
|
-
|
90
|
-
def flags(key, value)
|
91
|
-
@next_flags = Hash.new if @next_flags.nil?
|
92
|
-
@next_flags[key] = value
|
93
|
-
end
|
94
|
-
|
95
|
-
def alias(a, b)
|
96
|
-
@aliases = Hash.new if @aliases.nil?
|
97
|
-
@aliases[a] = b
|
98
|
-
end
|
99
|
-
|
100
|
-
def load_commands
|
101
|
-
Dir[File.join(File.dirname(__FILE__), 'commands', '*.rb')].each do |path|
|
102
|
-
Appli.module_eval File.read(path), path
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def parse_options(args)
|
107
|
-
idx = 0
|
108
|
-
args.clone.inject({}) do |memo, arg|
|
109
|
-
case arg
|
110
|
-
when /^--(.+?)=(.*)/
|
111
|
-
args.delete_at(idx)
|
112
|
-
memo.merge($1.to_sym => $2)
|
113
|
-
when /^--(.+)/
|
114
|
-
args.delete_at(idx)
|
115
|
-
memo.merge($1.to_sym => true)
|
116
|
-
when "--"
|
117
|
-
args.delete_at(idx)
|
118
|
-
return memo
|
119
|
-
else
|
120
|
-
idx += 1
|
121
|
-
memo
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
Appli.desc "Displays this help message"
|
128
|
-
Appli.usage "cb help [command]"
|
129
|
-
Appli.command "help", :global => true do |command|
|
130
|
-
if command.nil?
|
131
|
-
puts "The Appli Gem allows you to easily access your Appli account functions from the"
|
132
|
-
puts "command line. The functions below outline the options which are currently"
|
133
|
-
puts "available."
|
134
|
-
puts
|
135
|
-
puts "\e[31mGlobal Commands\e[0m"
|
136
|
-
puts "-" * 80
|
137
|
-
puts
|
138
|
-
for key, command in Appli.global_commands.sort_by{|k,v| k}
|
139
|
-
puts " \e[36m#{key.rjust(15)}\e[0m #{command[:description].first}"
|
140
|
-
end
|
141
|
-
puts
|
142
|
-
puts "\e[31mApplication Specific Commands\e[0m"
|
143
|
-
puts "-" * 80
|
144
|
-
|
145
|
-
puts "The following commands can be executed by running 'appli [identifier] {command}'"
|
146
|
-
puts
|
147
|
-
for key, command in Appli.application_commands.sort_by{|k,v| k}
|
148
|
-
description = command[:description].first
|
149
|
-
description = description[0,55] + '...' if description.size > 55
|
150
|
-
puts " \e[36m#{key.rjust(15)}\e[0m #{description}"
|
151
|
-
end
|
152
|
-
|
153
|
-
puts
|
154
|
-
puts "For more information see http://www.applihq.com/gem"
|
155
|
-
puts "See 'appli help [command]' for usage information."
|
156
|
-
else
|
157
|
-
if c = Appli.commands[command]
|
158
|
-
puts c[:description]
|
159
|
-
if c[:usage]
|
160
|
-
puts
|
161
|
-
puts "Usage:"
|
162
|
-
puts " #{c[:usage]}"
|
163
|
-
end
|
164
|
-
if c[:flags]
|
165
|
-
puts
|
166
|
-
puts "Options:"
|
167
|
-
for key, value in c[:flags]
|
168
|
-
puts " #{key.ljust(15)} #{value}"
|
169
|
-
end
|
170
|
-
end
|
171
|
-
else
|
172
|
-
puts "Command Not Found. Check 'appli help' for a full list of commands available to you."
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
Appli.desc "Displays the current version number"
|
178
|
-
Appli.usage "cb version"
|
179
|
-
Appli.command "version", :global => true do
|
180
|
-
puts "Appli Gem Version #{Appli::VERSION}"
|
181
|
-
end
|
data/lib/commands/apps.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
desc 'Display a list of all applications which you have access to'
|
2
|
-
usage "appli list"
|
3
|
-
command "list", :global => true do
|
4
|
-
apps = get("applications")
|
5
|
-
|
6
|
-
hash = [[:name, "Name", 30], [:identifier , "Identifier", 30], [:ssh_port, "SSH Port", 12], [:host, "Host", 30]]
|
7
|
-
total = hash.inject(0) {|e,r| e + r.last}
|
8
|
-
puts "-" * total
|
9
|
-
for item in hash
|
10
|
-
key, value, chars = item
|
11
|
-
print value.to_s.ljust(chars)
|
12
|
-
end
|
13
|
-
puts
|
14
|
-
puts "-" * total
|
15
|
-
for app in apps.sort_by {|a| a['application']['name'].upcase }
|
16
|
-
for item in hash
|
17
|
-
key, value, chars = item
|
18
|
-
data = case key
|
19
|
-
when :host then app['application']['host']['name']
|
20
|
-
else
|
21
|
-
app['application'][key.to_s].to_s
|
22
|
-
end
|
23
|
-
print data.ljust(chars)
|
24
|
-
end
|
25
|
-
puts
|
26
|
-
end
|
27
|
-
puts "-" * total
|
28
|
-
end
|
29
|
-
|
30
|
-
desc "Create a new application with the provided identifier"
|
31
|
-
usage "appli create {identifier}"
|
32
|
-
command "create", :global => true, :required_args => 1 do |identifier|
|
33
|
-
puts "Creating new application with identifier '#{identifier}'. Please wait - this may take a few minutes."
|
34
|
-
result = api('applications', {:application => {:identifier => identifier, :name => identifier}}.to_json)
|
35
|
-
if errors
|
36
|
-
puts "\nAn error occured while creating your application:"
|
37
|
-
display_errors
|
38
|
-
puts
|
39
|
-
Process.exit(1)
|
40
|
-
else
|
41
|
-
application = JSON.parse(result)['application']
|
42
|
-
puts "\n\e[44;37mApplication has been built successfully and is now running on '#{application['host'] ? application['host']['name'] : 'unknown host'}'.\e[0m"
|
43
|
-
puts
|
44
|
-
puts "You can now use a number of commands to work with your application, see documentation at www.applihq.com for"
|
45
|
-
puts "full details. You can also manage the application using your web browser at the domain above."
|
46
|
-
puts
|
47
|
-
puts "You may be looking for one of the following commands:"
|
48
|
-
puts
|
49
|
-
puts " * appli #{identifier} ssh"
|
50
|
-
puts " * appli #{identifier} db:import"
|
51
|
-
puts " * appli #{identifier} db:console"
|
52
|
-
puts " * appli #{identifier} capify config/deploy.rb"
|
53
|
-
puts
|
54
|
-
end
|
55
|
-
end
|
data/lib/commands/cap.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
desc 'Generates a pre-configured capistrano deployment recipe.'
|
2
|
-
usage "appli [application] capify {export path}"
|
3
|
-
command "capify", :required_args => 1 do |file|
|
4
|
-
contents = get("applications/#{@options[:application]}/capistrano")['config']
|
5
|
-
|
6
|
-
## Insert the Repository URL if we can...
|
7
|
-
repository_url = `git config remote.origin.url`
|
8
|
-
if $?.success?
|
9
|
-
contents.gsub!(/git\@\[...\]/, repository_url.chomp)
|
10
|
-
end
|
11
|
-
|
12
|
-
## Add the current branch name
|
13
|
-
branch_name = `git status > /dev/null 2>&1`.split("\n").first
|
14
|
-
if $?.success?
|
15
|
-
branch_name branch_name.split(/\s+/).last
|
16
|
-
contents.gsub!(/set \:branch, \"master\"/, "set :branch, \"#{branch_name.chomp}\"")
|
17
|
-
end
|
18
|
-
|
19
|
-
## Add any configuration files from your local config/ folder if you have one
|
20
|
-
if File.directory?('config')
|
21
|
-
config_files = Dir["config/*.yml"].map{|f| f.split('/').last }
|
22
|
-
contents.gsub!(/\%w\{ database\.yml \}/, "%w{ #{config_files.join(' ')} }")
|
23
|
-
end
|
24
|
-
|
25
|
-
File.open(file, 'w') {|f| f.write(contents) }
|
26
|
-
puts "Generated capistrano deployment receipe at '#{file}'."
|
27
|
-
puts
|
28
|
-
puts "You should now edit this file to include the path to your repository. Along with any additional"
|
29
|
-
puts "configuration which may be required by your application."
|
30
|
-
end
|
data/lib/commands/db.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
desc 'Create a MySQL console connection for your first database'
|
2
|
-
usage "appli [application] mysql"
|
3
|
-
command "db:console" do
|
4
|
-
database = get("applications/#{@options[:application]}/databases").first
|
5
|
-
if database
|
6
|
-
database = database['database']
|
7
|
-
puts "Connecting to database '#{database['name']}' on '#{database['host']['name']}'"
|
8
|
-
exec("ssh -t -p #{application['ssh_port']} app@#{host['name']} mysql -u #{database['username']} -p#{database['password']} -h #{database['host']['name']} #{database['name']}")
|
9
|
-
else
|
10
|
-
error("No database was not found for this application.")
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
desc 'Import a named MySQL file'
|
15
|
-
usage "appli [application] db:import {database number} {path to import mysql dump}"
|
16
|
-
command "db:import" do |number, path|
|
17
|
-
error("Import file not found at '#{path}'") unless File.exist?(path)
|
18
|
-
database = get("applications/#{@options[:application]}/databases/#{number}")
|
19
|
-
if database
|
20
|
-
database = database['database']
|
21
|
-
puts "Uploading MySQL export to server..."
|
22
|
-
remote_exec("rm -f ~/.appli_import.sql")
|
23
|
-
system("scp -P #{application['ssh_port']} #{path} app@#{host['name']}:~/.appli_import.sql")
|
24
|
-
puts "Importing database into '#{database['name']}' on '#{database['host']['name']}'..."
|
25
|
-
remote_exec("mysql -u #{database['username']} -p#{database['password']} -h #{database['host']['name']} #{database['name']} < ~/.appli_import.sql")
|
26
|
-
else
|
27
|
-
error "No database was found with number '#{number}'"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
desc 'List all databases on this application'
|
32
|
-
usage "appli [application] db:lists"
|
33
|
-
command "db:list" do
|
34
|
-
puts '-' * 80
|
35
|
-
print 'Name'.ljust(15)
|
36
|
-
print 'Username'.ljust(15)
|
37
|
-
print 'Password'.ljust(15)
|
38
|
-
print 'Host'.ljust(25)
|
39
|
-
puts
|
40
|
-
puts '-' * 80
|
41
|
-
|
42
|
-
for database in get("applications/#{@options[:application]}/databases")
|
43
|
-
database = database['database']
|
44
|
-
print database['name'].ljust(15)
|
45
|
-
print database['username'].ljust(15)
|
46
|
-
print database['password'].ljust(15)
|
47
|
-
print database['host']['name'].ljust(25)
|
48
|
-
puts
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
desc 'Create a new database with the entered label'
|
53
|
-
usage 'appli [application] db:create {label}'
|
54
|
-
command "db:create", :required_args => 1 do |*label|
|
55
|
-
label = label.join(' ')
|
56
|
-
if db = api_on_app('databases', {:database => {:label => label}}.to_json)
|
57
|
-
puts "Database has been created successfully. Connection details can be found below:"
|
58
|
-
db = JSON.parse(db)['database']
|
59
|
-
puts
|
60
|
-
puts " Label.............: #{db['label']}"
|
61
|
-
puts " Database Name.....: #{db['name']}"
|
62
|
-
puts " Username..........: #{db['username']}"
|
63
|
-
puts " Password..........: #{db['password']}"
|
64
|
-
puts " Host..............: #{db['host']['name']}"
|
65
|
-
puts
|
66
|
-
else
|
67
|
-
puts "Database could not be created."
|
68
|
-
display_errors
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
desc 'Dump the database schema'
|
73
|
-
usage "appli [application] db:export {db number} {file}"
|
74
|
-
command "db:export", :required_args => 2 do |number, file|
|
75
|
-
if database = get("applications/#{@options[:application]}/databases/#{number}")['database']
|
76
|
-
dump = remote_exec("mysqldump -u #{database['username']} -p#{database['password']} -h #{database['host']['name']} #{database['name']}")
|
77
|
-
File.open(file, 'w') {|f| f.write(dump) }
|
78
|
-
puts "MySQL dump written to '#{file}'. It was #{dump.size} bytes"
|
79
|
-
else
|
80
|
-
error "Database not found with #{number}. Check 'appli [application] db:list'"
|
81
|
-
end
|
82
|
-
end
|
data/lib/commands/domains.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
desc 'List all domains configured for this application'
|
2
|
-
usage "appli [application] domains:list"
|
3
|
-
command "domains:list" do
|
4
|
-
domains = JSON.parse(api_on_app("domains"))
|
5
|
-
for domain in domains
|
6
|
-
extra = ''
|
7
|
-
extra = '(primary)' if domain['domain']['primary']
|
8
|
-
extra = '(redirect)' if domain['domain']['redirect']
|
9
|
-
puts " * #{domain['domain']['domain']} #{extra}"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
desc "Add a new domain for this application"
|
14
|
-
usage "appli [application] domains:add {domain} {options}"
|
15
|
-
command "domains:add", :required_args => 1 do |name, options|
|
16
|
-
options = "" if options.nil?
|
17
|
-
if api_on_app("domains", {:domain => {:domain => name, :redirect => options.include?('redirect')}}.to_json)
|
18
|
-
puts "Domain '#{name}' added successfully."
|
19
|
-
else
|
20
|
-
puts "An error occured while adding your domain:"
|
21
|
-
display_errors
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
desc 'Remove a domain from this application'
|
26
|
-
usage "appli [application] domains:remove {domain}"
|
27
|
-
command "domains:remove", :required_args => 1 do |name|
|
28
|
-
domains = JSON.parse(api_on_app('domains'))
|
29
|
-
domain = domains.select{|d| d['domain']['domain'] == name}.first
|
30
|
-
if domain
|
31
|
-
if api_on_app("domains/#{domain['domain']['id']}", nil, :delete)
|
32
|
-
puts "Domain ('#{name}') removed successfully"
|
33
|
-
else
|
34
|
-
error "Domain could not be removed at this time."
|
35
|
-
end
|
36
|
-
else
|
37
|
-
error "Domain ('#{name}') does not exist within this application"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
data/lib/commands/gems.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
class FakeGemfile
|
2
|
-
attr_reader :gems, :sources
|
3
|
-
|
4
|
-
def initialize
|
5
|
-
@sources, @gems = [], []
|
6
|
-
end
|
7
|
-
|
8
|
-
def gem(name, version = nil, options = {})
|
9
|
-
@gems << {:name => name, :version => version, :options => options}
|
10
|
-
end
|
11
|
-
|
12
|
-
def method_missing(name, *values, &block)
|
13
|
-
yield block if block_given?
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
desc "Read in the specified Gemfile and install all the required gems on your application"
|
18
|
-
usage "appli [application] gems:import {path to file}"
|
19
|
-
command "gems:import" do |file|
|
20
|
-
file_to_import = File.expand_path(file || 'Gemfile')
|
21
|
-
unless File.exist?(file_to_import)
|
22
|
-
raise Error, "Gemfile was not found at #{file_to_import}"
|
23
|
-
end
|
24
|
-
|
25
|
-
puts "Importing gems from #{file_to_import}"
|
26
|
-
gem_details = FakeGemfile.new
|
27
|
-
gem_details.instance_eval(File.read(file_to_import), file_to_import)
|
28
|
-
|
29
|
-
puts "There are #{gem_details.gems.size} gem(s) to install on your application."
|
30
|
-
for g in gem_details.gems[0,4]
|
31
|
-
puts "Installing #{g[:name]} (#{g[:version] || 'latest'})"
|
32
|
-
data = {:ruby_gem => {:name => g[:name], :version => g[:version]}}.to_json
|
33
|
-
if api_on_app "ruby_gems", data
|
34
|
-
puts "=> Installed successfully"
|
35
|
-
else
|
36
|
-
puts "=> Installation failed"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
desc "Install the provided gem on your application's container"
|
42
|
-
usage "appli [application] gems:install {gem name} {version]"
|
43
|
-
command "gems:install", :required_args => 1 do |name, version|
|
44
|
-
puts "Installing #{name} (#{version || 'latest'})"
|
45
|
-
data = {:ruby_gem => {:name => name, :version => version || ''}}.to_json
|
46
|
-
if a = api_on_app("ruby_gems", data)
|
47
|
-
puts "=> Installed"
|
48
|
-
else
|
49
|
-
puts errors.inspect
|
50
|
-
puts "=> Install failed"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
desc "List all installed gems for your application"
|
55
|
-
usage "appli gems"
|
56
|
-
command "gems" do
|
57
|
-
ssh "gem list"
|
58
|
-
end
|
data/lib/commands/keys.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
desc "Upload your local public key to your appli user account"
|
2
|
-
usage "appli keys:add {key file}"
|
3
|
-
command "keys:add", :global => true do |file|
|
4
|
-
file = "#{ENV['HOME']}/.ssh/id_rsa.pub" if file.nil?
|
5
|
-
error("Key file not found at '#{file}'") unless File.file?(file)
|
6
|
-
key_data = File.read(file).chomp
|
7
|
-
data = {:key => {:key => key_data}}.to_json
|
8
|
-
if api("settings/keys", data)
|
9
|
-
puts "SSH key uploaded successfully from '#{file}'"
|
10
|
-
else
|
11
|
-
puts "Sorry, an error occured while adding your key. Please check the errors below:"
|
12
|
-
display_errors
|
13
|
-
end
|
14
|
-
end
|
data/lib/commands/logs.rb
DELETED
data/lib/commands/ssh.rb
DELETED
data/lib/commands/stats.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
desc "Display system memory usage"
|
2
|
-
usage "appli mem:system"
|
3
|
-
command "mem:system" do
|
4
|
-
puts remote_exec("free -m").split("\n")[0,2].join("\n")
|
5
|
-
end
|
6
|
-
|
7
|
-
desc 'Display passenger memory statistics'
|
8
|
-
usage "appli mem:passenger"
|
9
|
-
command "mem:passenger" do
|
10
|
-
ssh "passenger-memory-stats", /^\*\*\* WARNING\:(.*)$/
|
11
|
-
end
|
12
|
-
|
13
|
-
desc 'Display your current disk space usage'
|
14
|
-
usage "appli diskusage"
|
15
|
-
command "diskusage" do
|
16
|
-
output = remote_exec("df -h").split("\n")[1]
|
17
|
-
output = output.split(/\s+/)
|
18
|
-
fs, size, usage, available, usage_percent, mountpoint = output
|
19
|
-
puts "You are using #{usage} (including system files)."
|
20
|
-
puts
|
21
|
-
puts "You are not billed for system file usage - only files & gems which"
|
22
|
-
puts "you place within your hosting area."
|
23
|
-
puts
|
24
|
-
puts "Your system is limited to #{size} however if you need additional"
|
25
|
-
puts "space, please just contact support."
|
26
|
-
end
|