preview_add 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +26 -0
- data/Rakefile +1 -0
- data/bin/preview_add +79 -0
- data/lib/preview_add/config.rb +20 -0
- data/lib/preview_add/dns.rb +54 -0
- data/lib/preview_add/names.rb +18 -0
- data/lib/preview_add/svn.rb +13 -0
- data/lib/preview_add/version.rb +3 -0
- data/lib/preview_add/vhost.erb +10 -0
- data/lib/preview_add/vhost.rb +86 -0
- data/lib/preview_add.rb +45 -0
- data/preview_add.gemspec +22 -0
- metadata +94 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
preview_add
|
2
|
+
===========
|
3
|
+
|
4
|
+
Add preview sites.
|
5
|
+
|
6
|
+
Add preview sites for the specified host. Creates the DNS, Vhost, htpasswd file and checks the site out from revision control
|
7
|
+
|
8
|
+
Installation
|
9
|
+
------------
|
10
|
+
|
11
|
+
$ gem install preview_add
|
12
|
+
|
13
|
+
preview_add requires a config file in /etc/preview_add, the structure should look like:
|
14
|
+
|
15
|
+
---
|
16
|
+
:preview_domain: flickerbox.com
|
17
|
+
:svn_repos: https://repos.com
|
18
|
+
:locations:
|
19
|
+
:htpasswd: /path/to/htpasswd/directory
|
20
|
+
:vhosts: /path/to/vhosts/directory
|
21
|
+
:sites_available: /path/to/sites_available/directory
|
22
|
+
:zerigo:
|
23
|
+
:user: zerigo_user
|
24
|
+
:api_key: zerigo_api_key
|
25
|
+
:zone_id: zone_id
|
26
|
+
:cname: the cname to the preview domain
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/preview_add
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#/ Usage: preview_add <options> <host>...
|
3
|
+
#/
|
4
|
+
#/ The host should be the host of the live site, not the preview site.
|
5
|
+
#/
|
6
|
+
#/ Add preview sites for the specified host. Creates the DNS, Vhost, htpasswd
|
7
|
+
#/ file and checks the site out from revision control
|
8
|
+
#/
|
9
|
+
#/ Options
|
10
|
+
#/ -f, --htpasswd specify the htpasswd file to use
|
11
|
+
#/ -u, --username username for the htpasswd file
|
12
|
+
#/ -p, --password password for the htpasswd file
|
13
|
+
#/ -h, --help show this help message
|
14
|
+
require 'preview_add'
|
15
|
+
require 'optparse'
|
16
|
+
|
17
|
+
if ENV['USER'] != 'root'
|
18
|
+
puts "You must run preview_add as root"
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
def usage
|
23
|
+
puts File.readlines(__FILE__).
|
24
|
+
grep(/^#\/.*/).
|
25
|
+
map { |line| line.chomp[3..-1] }.
|
26
|
+
join("\n")
|
27
|
+
end
|
28
|
+
|
29
|
+
options = {}
|
30
|
+
|
31
|
+
optparse = OptionParser.new do |opts|
|
32
|
+
|
33
|
+
opts.on( '-f', '--htpasswd [file]') do |arg|
|
34
|
+
options[:htpasswd] = arg
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on( '-u', '--username [username]') do |arg|
|
38
|
+
options[:username] = arg
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on( '-p', '--password [password]') do |arg|
|
42
|
+
options[:password] = arg
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on('-v', '--version') do
|
46
|
+
puts PreviewAdd::VERSION
|
47
|
+
exit 0
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on('-h', '--help', 'Display help info') do
|
51
|
+
usage
|
52
|
+
exit 0
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
begin
|
57
|
+
optparse.parse!
|
58
|
+
|
59
|
+
# The url has no flag and will be in ARGV[0] if it's set
|
60
|
+
options[:host] = ARGV[0] || nil
|
61
|
+
|
62
|
+
# Reset ARGV for gets later
|
63
|
+
ARGV.clear
|
64
|
+
|
65
|
+
mandatory = [:host]
|
66
|
+
missing = mandatory.select{ |param| options[param].nil? }
|
67
|
+
unless missing.empty?
|
68
|
+
puts "Missing option#{'s' if missing.length > 1}: #{missing.join(', ')}"
|
69
|
+
usage
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
73
|
+
puts $!.to_s
|
74
|
+
usage
|
75
|
+
exit 1
|
76
|
+
end
|
77
|
+
|
78
|
+
preview = PreviewAdd::PreviewAdd.new(options)
|
79
|
+
preview.add_site
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module PreviewAdd
|
4
|
+
|
5
|
+
class Config
|
6
|
+
|
7
|
+
FILE = "/etc/preview_add"
|
8
|
+
|
9
|
+
def self.config
|
10
|
+
if File.exist?(FILE)
|
11
|
+
YAML.load_file(FILE)
|
12
|
+
else
|
13
|
+
puts "Please create a config file in /etc/preview_add"
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'zerigo_dns'
|
3
|
+
|
4
|
+
module PreviewAdd
|
5
|
+
class Dns
|
6
|
+
|
7
|
+
def initialize(options, host)
|
8
|
+
Zerigo::DNS::Base.user = options[:zerigo][:user]
|
9
|
+
Zerigo::DNS::Base.password = options[:zerigo][:api_key]
|
10
|
+
Zerigo::DNS::Base.format = :xml
|
11
|
+
|
12
|
+
@zone_id = options[:zerigo][:zone_id]
|
13
|
+
@host = host
|
14
|
+
@cname = options[:preview_domain]
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_cname
|
18
|
+
vals = {
|
19
|
+
:hostname => @host,
|
20
|
+
:host_type => 'CNAME',
|
21
|
+
:data => @cname,
|
22
|
+
:zone_id => @zone_id
|
23
|
+
}
|
24
|
+
|
25
|
+
begin
|
26
|
+
Zerigo::DNS::Host.create(vals)
|
27
|
+
rescue Exception => e
|
28
|
+
if e.to_s.include? 'wrong number of arguments (2 for 1)'
|
29
|
+
puts "Successfully created #{@host}.#{@cname}"
|
30
|
+
else
|
31
|
+
puts e
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def record_exists?(hostname)
|
38
|
+
begin
|
39
|
+
hosts = Zerigo::DNS::Host.find(:all, :params=>{:zone_id => @zone_id})
|
40
|
+
hosts.any? { |hash| hash.hostname == hostname }
|
41
|
+
rescue Exception => e
|
42
|
+
puts e
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_if_not_exists
|
48
|
+
unless record_exists? @host
|
49
|
+
add_cname
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module PreviewAdd
|
2
|
+
class Names
|
3
|
+
|
4
|
+
attr_reader :document_root, :domain, :server_name, :host, :base_name
|
5
|
+
|
6
|
+
def initialize(host)
|
7
|
+
@host = host.dup
|
8
|
+
@host.gsub!(/^(https?:\/\/)?(www\.)?/, '')
|
9
|
+
|
10
|
+
parts = @host.split('.')
|
11
|
+
@document_root = parts.reverse.join('.')
|
12
|
+
@domain = parts[-2, 2].reverse.join('.')
|
13
|
+
@server_name = parts[0..-2].join('.')
|
14
|
+
@base_name = parts[-2]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module PreviewAdd
|
2
|
+
class Svn
|
3
|
+
|
4
|
+
def self.co(config, names)
|
5
|
+
url = "#{config[:svn_repos]}/#{names.document_root}/trunk/"
|
6
|
+
doc_root = "#{config[:locations][:vhosts]}/#{names.document_root}/"
|
7
|
+
system "svn co #{url} #{doc_root}"
|
8
|
+
system "chown -R webmaster:webmaster #{doc_root}"
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<VirtualHost *:80>
|
2
|
+
ServerName <%= @server_name %>
|
3
|
+
DocumentRoot <%= @document_root %>
|
4
|
+
<Directory <%= @document_root %>>
|
5
|
+
AuthName "Preview Website"
|
6
|
+
AuthType Basic
|
7
|
+
AuthUserFile <%= @auth_user_file %>
|
8
|
+
Require valid-user
|
9
|
+
</Directory>
|
10
|
+
</VirtualHost>
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module PreviewAdd
|
5
|
+
class Vhost
|
6
|
+
|
7
|
+
include FileUtils
|
8
|
+
|
9
|
+
attr_accessor :vhost
|
10
|
+
|
11
|
+
def initialize(config, names)
|
12
|
+
@host = config[:host]
|
13
|
+
|
14
|
+
@config = config
|
15
|
+
@names = names
|
16
|
+
|
17
|
+
@auth_name = 'TODO'
|
18
|
+
@auth_user_file = auth_user_file
|
19
|
+
@document_root = File.join(@config[:locations][:vhosts], @names.document_root)
|
20
|
+
@server_name = "#{@names.server_name}.#{@config[:preview_domain]}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def auth_user_file
|
24
|
+
htpasswd_dir = @config[:locations][:htpasswd];
|
25
|
+
extension = '.htpasswd'
|
26
|
+
auth_user_file = File.join(htpasswd_dir, "#{@names.domain + extension}")
|
27
|
+
|
28
|
+
unless @config[:htpasswd].nil?
|
29
|
+
if @config[:htpasswd].end_with?(extension)
|
30
|
+
auth_user_file = File.join(htpasswd_dir, "#{@config[:htpasswd]}")
|
31
|
+
else
|
32
|
+
auth_user_file = File.join(htpasswd_dir, "#{@config[:htpasswd] + extension}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
auth_user_file
|
37
|
+
end
|
38
|
+
|
39
|
+
def generate_vhost
|
40
|
+
template = File.join(File.dirname(__FILE__), 'vhost.erb')
|
41
|
+
vhost = ERB.new(File.read(template))
|
42
|
+
vhost.result(binding)
|
43
|
+
end
|
44
|
+
|
45
|
+
def htpasswd(username, password)
|
46
|
+
`htpasswd -bn #{username} #{password}`
|
47
|
+
end
|
48
|
+
|
49
|
+
def create!
|
50
|
+
# Create the document root
|
51
|
+
unless File.exist? @document_root
|
52
|
+
mkdir(@document_root)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Create the vhost
|
56
|
+
File.open(File.join(@config[:locations][:sites_available], @names.document_root), 'w') {
|
57
|
+
|f| f.write(generate_vhost)
|
58
|
+
}
|
59
|
+
|
60
|
+
# Create the htpasswd file if it doesn't exist
|
61
|
+
unless File.exists? @auth_user_file
|
62
|
+
username = @config[:username] || @names.base_name
|
63
|
+
password = @config[:password] || nil
|
64
|
+
|
65
|
+
if password.nil?
|
66
|
+
puts "No htpasswd file exists."
|
67
|
+
puts "Username: #{username}"
|
68
|
+
print "Password: "
|
69
|
+
password = gets.to_s.strip
|
70
|
+
end
|
71
|
+
|
72
|
+
File.open(@auth_user_file, 'w') { |f| f.write(htpasswd(username, password)) }
|
73
|
+
end
|
74
|
+
|
75
|
+
unless @config[:mode] == 'test'
|
76
|
+
# Enable the site
|
77
|
+
`a2ensite #{@names.document_root}`
|
78
|
+
|
79
|
+
# reload apache
|
80
|
+
`service apache2 reload`
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
data/lib/preview_add.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require "preview_add/version"
|
2
|
+
require "preview_add/config"
|
3
|
+
require "preview_add/names"
|
4
|
+
require "preview_add/dns"
|
5
|
+
require "preview_add/vhost"
|
6
|
+
require "preview_add/svn"
|
7
|
+
|
8
|
+
module PreviewAdd
|
9
|
+
class PreviewAdd
|
10
|
+
|
11
|
+
attr_reader :config, :names
|
12
|
+
|
13
|
+
def initialize(opts = {})
|
14
|
+
@config = Config.config.merge(opts)
|
15
|
+
@names = Names.new(@config[:host])
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_dns
|
19
|
+
dns = Dns.new(@config, @names.server_name)
|
20
|
+
dns.create_if_not_exists
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_vhost
|
24
|
+
vhost = Vhost.new(@config, @names)
|
25
|
+
vhost.create!
|
26
|
+
end
|
27
|
+
|
28
|
+
def checkout_site
|
29
|
+
Svn.co(@config, @names)
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_site
|
33
|
+
# Add DNS Entry
|
34
|
+
add_dns
|
35
|
+
|
36
|
+
# Add Vhost
|
37
|
+
add_vhost
|
38
|
+
|
39
|
+
# Checkout site
|
40
|
+
checkout_site
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
data/preview_add.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "preview_add/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "preview_add"
|
7
|
+
s.version = PreviewAdd::VERSION
|
8
|
+
s.authors = ["Ben Ubois"]
|
9
|
+
s.email = ["ben@benubois.com"]
|
10
|
+
s.homepage = "https://github.com/flickerbox/preview"
|
11
|
+
s.summary = %q{Add preview sites}
|
12
|
+
s.description = %q{Add preview sites for the specified host. Creates the DNS, Vhost, htpasswd file and checks the site out from revision control}
|
13
|
+
|
14
|
+
s.rubyforge_project = "preview"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency "zerigo_dns"
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: preview_add
|
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
|
+
- Ben Ubois
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-09-18 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: zerigo_dns
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description: Add preview sites for the specified host. Creates the DNS, Vhost, htpasswd file and checks the site out from revision control
|
36
|
+
email:
|
37
|
+
- ben@benubois.com
|
38
|
+
executables:
|
39
|
+
- preview_add
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files: []
|
43
|
+
|
44
|
+
files:
|
45
|
+
- .gitignore
|
46
|
+
- Gemfile
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- bin/preview_add
|
50
|
+
- lib/preview_add.rb
|
51
|
+
- lib/preview_add/config.rb
|
52
|
+
- lib/preview_add/dns.rb
|
53
|
+
- lib/preview_add/names.rb
|
54
|
+
- lib/preview_add/svn.rb
|
55
|
+
- lib/preview_add/version.rb
|
56
|
+
- lib/preview_add/vhost.erb
|
57
|
+
- lib/preview_add/vhost.rb
|
58
|
+
- preview_add.gemspec
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: https://github.com/flickerbox/preview
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
hash: 3
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project: preview
|
89
|
+
rubygems_version: 1.6.2
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: Add preview sites
|
93
|
+
test_files: []
|
94
|
+
|