gun 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/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +1 -0
- data/Rakefile +2 -0
- data/bin/.gun.swp +0 -0
- data/bin/gun +97 -0
- data/bin/gunify +179 -0
- data/gun.gemspec +23 -0
- data/lib/gun.rb +8 -0
- data/lib/gun/trigger.rb +14 -0
- data/lib/gun/version.rb +3 -0
- metadata +105 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 matt
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gun deployment gem barebones for now
|
data/Rakefile
ADDED
data/bin/.gun.swp
ADDED
Binary file
|
data/bin/gun
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'trollop'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
|
7
|
+
## Here's a program called "gun". We want this behavior:
|
8
|
+
##
|
9
|
+
## gun staging deploy => deploys code to staging
|
10
|
+
## gun production deploy => deploys to production
|
11
|
+
##
|
12
|
+
##
|
13
|
+
##
|
14
|
+
## There are some global options, which appear to the left of the subcommand.
|
15
|
+
## There are some subcommand options, which appear to the right.
|
16
|
+
##
|
17
|
+
## Subcommand options can be specific to the subcommand. 'staging' might take
|
18
|
+
## different options from 'production'.
|
19
|
+
##
|
20
|
+
## We do this by calling Trollop twice; one for the global options and once for
|
21
|
+
## the subcommand options. We need to tell Trollop what the subcommands are, so
|
22
|
+
## that it stops processing the global options when it encounters one of them.
|
23
|
+
|
24
|
+
SUB_COMMANDS = %w(staging production)
|
25
|
+
global_opts = Trollop::options do
|
26
|
+
banner "gun - simple trigger happy deployment"
|
27
|
+
#opt :dry_run, "Don't actually do anything", :short => "-n"
|
28
|
+
opt :staging, "Run a command on staging", :short => "-s"
|
29
|
+
opt :production, "Run a command on production", :short => "-p"
|
30
|
+
stop_on SUB_COMMANDS
|
31
|
+
end
|
32
|
+
|
33
|
+
##These are the default settings
|
34
|
+
machine = {
|
35
|
+
:location => 'nolocationselected',
|
36
|
+
:ssh_port => '22',
|
37
|
+
:ssh_user => 'root'
|
38
|
+
}
|
39
|
+
|
40
|
+
require File.join(Dir.pwd, 'lib/gun_trigger' )
|
41
|
+
|
42
|
+
cmd = ARGV.shift # get the command
|
43
|
+
sub_cmd = ARGV.shift # get the subcommand
|
44
|
+
cmd_opts = case cmd
|
45
|
+
when "staging" # parse delete options
|
46
|
+
Trollop::options do
|
47
|
+
opt :uname, "Check Kernel Version on staging server"
|
48
|
+
opt :deploy, "Deploy to staging server"
|
49
|
+
end
|
50
|
+
machine.merge!(GunTrigger::STAGING)
|
51
|
+
when "production" # parse delete options
|
52
|
+
Trollop::options do
|
53
|
+
opt :deploy, "Deploy to production server"
|
54
|
+
end
|
55
|
+
machine.merge!(GunTrigger::PRODUCTION)
|
56
|
+
else
|
57
|
+
usage =<<EOS
|
58
|
+
Usage:
|
59
|
+
gun [environment] [action]
|
60
|
+
where [environment] is:
|
61
|
+
staging
|
62
|
+
production
|
63
|
+
EOS
|
64
|
+
puts usage
|
65
|
+
Trollop::die "Unknown environment"
|
66
|
+
#Error unknown command"
|
67
|
+
#Trollop::options do
|
68
|
+
# opt :deploy, "Deploy to production server"
|
69
|
+
#end
|
70
|
+
end
|
71
|
+
|
72
|
+
gt = GunTrigger.new(machine)
|
73
|
+
|
74
|
+
sub_cmd_opts = case sub_cmd
|
75
|
+
when "uname"
|
76
|
+
puts 'Calling uname for ' + cmd
|
77
|
+
gt.uname
|
78
|
+
when "deploy"
|
79
|
+
puts 'Doing deployment for ' + cmd
|
80
|
+
gt.deploy
|
81
|
+
else
|
82
|
+
usage = ''
|
83
|
+
usage =<<EOS
|
84
|
+
Usage:
|
85
|
+
gun #{cmd} [action]
|
86
|
+
where [action] is:
|
87
|
+
deploy
|
88
|
+
uname
|
89
|
+
EOS
|
90
|
+
puts usage
|
91
|
+
end
|
92
|
+
|
93
|
+
#puts "Global options: #{global_opts.inspect}"
|
94
|
+
#puts "Subcommand: #{cmd.inspect}"
|
95
|
+
#puts "Subcommand options: #{cmd_opts.inspect}"
|
96
|
+
#puts "Remaining arguments: #{ARGV.inspect}"
|
97
|
+
|
data/bin/gunify
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
OptionParser.new do |opts|
|
7
|
+
opts.banner = "Usage: #{File.basename($0)} [path]"
|
8
|
+
|
9
|
+
opts.on("-h", "--help", "Displays this help info") do
|
10
|
+
puts opts
|
11
|
+
exit 0
|
12
|
+
end
|
13
|
+
|
14
|
+
begin
|
15
|
+
opts.parse!(ARGV)
|
16
|
+
rescue OptionParser::ParseError => e
|
17
|
+
warn e.message
|
18
|
+
puts opts
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
if ARGV.empty?
|
24
|
+
abort "Please specify the directory to gunify, e.g. `#{File.basename($0)} .'"
|
25
|
+
elsif !File.exists?(ARGV.first)
|
26
|
+
abort "`#{ARGV.first}' does not exist."
|
27
|
+
elsif !File.directory?(ARGV.first)
|
28
|
+
abort "`#{ARGV.first}' is not a directory."
|
29
|
+
elsif ARGV.length > 1
|
30
|
+
abort "Too many arguments; please specify only the directory to capify."
|
31
|
+
end
|
32
|
+
|
33
|
+
def unindent(string)
|
34
|
+
indentation = string[/\A\s*/]
|
35
|
+
string.strip.gsub(/^#{indentation}/, "")
|
36
|
+
end
|
37
|
+
|
38
|
+
files = {
|
39
|
+
"lib/gun_trigger.rb" => <<-FILE
|
40
|
+
require 'rye'
|
41
|
+
require 'fileutils'
|
42
|
+
|
43
|
+
|
44
|
+
class GunTrigger
|
45
|
+
|
46
|
+
STAGING = {
|
47
|
+
:project_name => 'thedepot',
|
48
|
+
:location => 'testthedepot.com',
|
49
|
+
:ssh_port => '2203',
|
50
|
+
:ssh_user => 'root',
|
51
|
+
:repository => "httpdocs/thedepot",
|
52
|
+
:local_checkout_directory => '/tmp',
|
53
|
+
:remote_release_directory => '/http/thedepot',
|
54
|
+
:remote_codebase_directory => '/usr/local/src/thedepot',
|
55
|
+
:public_folder_owner => 'dude:whiterussia',
|
56
|
+
:rails_root_owner => 'dude:whiterussia',
|
57
|
+
:product_images_folder => "public/images/products",
|
58
|
+
:remote_product_image_folder => "/var/www/vhosts/thedepto/public/images",
|
59
|
+
:db_file => "database.staging.yml"
|
60
|
+
}
|
61
|
+
|
62
|
+
PRODUCTION = {
|
63
|
+
:location => 'thedpot.com'
|
64
|
+
}
|
65
|
+
|
66
|
+
def initialize(machine)
|
67
|
+
@machine = machine
|
68
|
+
end
|
69
|
+
|
70
|
+
def uname
|
71
|
+
puts '+++Running uname'
|
72
|
+
lbox = Rye::Box.new( @machine[:location], { :port => @machine[:ssh_port], :user => @machine[:ssh_user]} )
|
73
|
+
puts lbox.uname(:a)
|
74
|
+
end
|
75
|
+
|
76
|
+
def deploy
|
77
|
+
puts '+++ Deploying to ' + @machine[:location]
|
78
|
+
#Rye::Cmd.add_command :
|
79
|
+
lbox = Rye::Box.new( @machine[:location], { :port => @machine[:ssh_port], :user => @machine[:ssh_user]} )
|
80
|
+
release_date = Time.now.strftime("%Y%m%d%H%M%S")
|
81
|
+
puts '+++ Creating folder ' + release_date
|
82
|
+
checkout_code( @machine[:local_checkout_directory], release_date )
|
83
|
+
puts "+++ Running copy"
|
84
|
+
copy_code( lbox, release_date )
|
85
|
+
#do mysql related stuff here
|
86
|
+
run_bundler(lbox, release_date)
|
87
|
+
run_migrations(lbox, release_date)
|
88
|
+
link_to_current_codebase(lbox, release_date)
|
89
|
+
set_permissions(lbox, release_date)
|
90
|
+
restart_webserver(lbox)
|
91
|
+
end
|
92
|
+
|
93
|
+
def set_permissions(box, release_date)
|
94
|
+
box.chown "-R", @machine[:rails_root_owner], File.join(@machine[:remote_codebase_directory], release_date )
|
95
|
+
box.chown "-R", @machine[:public_folder_owner], File.join(@machine[:remote_codebase_directory], release_date, "public" )
|
96
|
+
box.chown "-R", @machine[:rails_root_owner], File.join(@machine[:remote_codebase_directory], "current")
|
97
|
+
box.chown "-R", @machine[:public_folder_owner], File.join(@machine[:remote_codebase_directory], "current", "public" )
|
98
|
+
end
|
99
|
+
|
100
|
+
def run_migrations(box, release_date)
|
101
|
+
puts box.mv File.join(@machine[:remote_codebase_directory], release_date, "config", @machine[:db_file]), File.join(@machine[:remote_codebase_directory], release_date, "config", 'database.yml')
|
102
|
+
puts box.rake "-f", File.join(@machine[:remote_codebase_directory], release_date, "Rakefile"), "db:migrate", "RAILS_ENV=production"
|
103
|
+
end
|
104
|
+
|
105
|
+
def run_bundler(box, release_date)
|
106
|
+
box.disable_safe_mode
|
107
|
+
cmd = "cd " + File.join(@machine[:remote_codebase_directory], release_date) + "; " + 'bundle install'
|
108
|
+
puts "+++ Running " + cmd
|
109
|
+
puts box.execute cmd
|
110
|
+
box.enable_safe_mode
|
111
|
+
end
|
112
|
+
|
113
|
+
def link_to_current_codebase(box, release_date)
|
114
|
+
box.disable_safe_mode
|
115
|
+
puts "+++ Running rm -f " + File.join(@machine[:remote_codebase_directory], "current")
|
116
|
+
puts box.rm '-f', File.join(@machine[:remote_codebase_directory], "current")
|
117
|
+
puts "+++ Running ln -s " + File.join(@machine[:remote_codebase_directory], release_date) + " " + File.join(@machine[:remote_codebase_directory], "current")
|
118
|
+
puts box.ln "-s", File.join(@machine[:remote_codebase_directory], release_date), File.join(@machine[:remote_codebase_directory], "current")
|
119
|
+
remote_images_dest_folder = File.join(@machine[:remote_codebase_directory], "current", @machine[:product_images_folder])
|
120
|
+
puts "+++ Running rm -fr " + remote_images_dest_folder
|
121
|
+
puts box.rm '-fr', remote_images_dest_folder
|
122
|
+
box.enable_safe_mode
|
123
|
+
puts "+++ Running ln -s " + @machine[:remote_product_image_folder] + " " + remote_images_dest_folder
|
124
|
+
puts box.ln "-s", @machine[:remote_product_image_folder], remote_images_dest_folder
|
125
|
+
end
|
126
|
+
|
127
|
+
def restart_webserver(box)
|
128
|
+
box.disable_safe_mode
|
129
|
+
puts box.execute "service httpd restart"
|
130
|
+
box.enable_safe_mode
|
131
|
+
end
|
132
|
+
|
133
|
+
def copy_code( box, release_date )
|
134
|
+
#tarball the code
|
135
|
+
cmd = "cd " + @machine[:local_checkout_directory] + "; tar czvf " + @machine[:project_name] + ".tar.gz " + "./" + release_date
|
136
|
+
puts '+++ running ' + cmd
|
137
|
+
system(cmd)
|
138
|
+
#copy code
|
139
|
+
puts '+++ running file upload ' + File.join(@machine[:local_checkout_directory], @machine[:project_name] + '.tar.gz') + ' to ' + File.join(@machine[:remote_codebase_directory], @machine[:project_name] + ".tar.gz")
|
140
|
+
box.file_upload File.join(@machine[:local_checkout_directory], @machine[:project_name] + '.tar.gz'), File.join(@machine[:remote_codebase_directory], @machine[:project_name] + ".tar.gz")
|
141
|
+
#unzip code
|
142
|
+
puts "+++ running tar -xzv " + File.join(@machine[:remote_codebase_directory], @machine[:project_name] + '.tar.gz')
|
143
|
+
#box.run_command "tar -xzvf " + File.join(@machine[:remote_codebase_directory], @machine[:project_name] + '.tar.gz')
|
144
|
+
box.cd @machine[:remote_codebase_directory]
|
145
|
+
puts box.tar "-xzvf", File.join(@machine[:remote_codebase_directory], @machine[:project_name] + '.tar.gz')
|
146
|
+
end
|
147
|
+
|
148
|
+
def checkout_code(rlocation, sfolder)
|
149
|
+
FileUtils.mkdir( rlocation + '/' + sfolder )
|
150
|
+
cmd = "cd " + rlocation + ";cvs checkout -d ./" + sfolder + " " + @machine[:repository]
|
151
|
+
puts "+++ Running " + cmd
|
152
|
+
system(cmd)
|
153
|
+
end
|
154
|
+
|
155
|
+
def rollback
|
156
|
+
end
|
157
|
+
end
|
158
|
+
FILE
|
159
|
+
}
|
160
|
+
|
161
|
+
base = ARGV.shift
|
162
|
+
files.each do |file, content|
|
163
|
+
file = File.join(base, file)
|
164
|
+
if File.exists?(file)
|
165
|
+
warn "[skip] '#{file}' already exists"
|
166
|
+
elsif File.exists?(file.downcase)
|
167
|
+
warn "[skip] '#{file.downcase}' exists, which could conflict with `#{file}'"
|
168
|
+
else
|
169
|
+
unless File.exists?(File.dirname(file))
|
170
|
+
puts "[add] making directory '#{File.dirname(file)}'"
|
171
|
+
FileUtils.mkdir(File.dirname(file))
|
172
|
+
end
|
173
|
+
puts "[add] writing '#{file}'"
|
174
|
+
File.open(file, "w") { |f| f.write(content) }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
puts "[done] gunified!"
|
179
|
+
|
data/gun.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/gun/version', __FILE__)
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.authors = ["Matt Carr"]
|
5
|
+
gem.email = ["bikokid@gmail.com"]
|
6
|
+
|
7
|
+
gem.files = `git ls-files`.split($\)
|
8
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
9
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
10
|
+
gem.name = 'gun'
|
11
|
+
gem.require_paths = ["lib"]
|
12
|
+
gem.version = Gun::VERSION
|
13
|
+
|
14
|
+
gem.requirements = "Gun requires trollop, and rye gems to run."
|
15
|
+
|
16
|
+
gem.add_dependency("trollop")
|
17
|
+
gem.add_dependency("rye")
|
18
|
+
|
19
|
+
gem.date = '2012-08-19'
|
20
|
+
gem.summary = "Gun for deployment"
|
21
|
+
gem.description = "Deploy your applications with the simple pull of a trigger"
|
22
|
+
gem.homepage = 'http://rubygems.org/gems/gun'
|
23
|
+
end
|
data/lib/gun.rb
ADDED
data/lib/gun/trigger.rb
ADDED
data/lib/gun/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gun
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Matt Carr
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-08-19 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: trollop
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rye
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
description: Deploy your applications with the simple pull of a trigger
|
49
|
+
email:
|
50
|
+
- bikokid@gmail.com
|
51
|
+
executables:
|
52
|
+
- .gun.swp
|
53
|
+
- gun
|
54
|
+
- gunify
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- Gemfile
|
61
|
+
- LICENSE
|
62
|
+
- README.md
|
63
|
+
- Rakefile
|
64
|
+
- bin/.gun.swp
|
65
|
+
- bin/gun
|
66
|
+
- bin/gunify
|
67
|
+
- gun.gemspec
|
68
|
+
- lib/gun.rb
|
69
|
+
- lib/gun/trigger.rb
|
70
|
+
- lib/gun/version.rb
|
71
|
+
homepage: http://rubygems.org/gems/gun
|
72
|
+
licenses: []
|
73
|
+
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 3
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
version: "0"
|
97
|
+
requirements:
|
98
|
+
- Gun requires trollop, and rye gems to run.
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 1.8.24
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: Gun for deployment
|
104
|
+
test_files: []
|
105
|
+
|