gun 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gun.gemspec
4
+ gemspec
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.
@@ -0,0 +1 @@
1
+ Gun deployment gem barebones for now
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
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
+
@@ -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
+
@@ -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
@@ -0,0 +1,8 @@
1
+ class Gun
2
+ def self.pull_trigger(setup = {})
3
+ trigger = Trigger.new(setup)
4
+ puts trigger.pull
5
+ end
6
+ end
7
+
8
+ require 'gun/trigger'
@@ -0,0 +1,14 @@
1
+
2
+ class Gun::Trigger
3
+ def initialize(setup)
4
+ @language = setup
5
+ end
6
+
7
+ def pull
8
+ if @setup.empty?
9
+ return "setup is empty"
10
+ else
11
+ return setup
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Gun
2
+ VERSION = "0.0.1"
3
+ end
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
+