hostess 0.1.2 → 0.1.6
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/README.md +3 -6
- data/Rakefile +11 -6
- data/bin/hostess +1 -139
- data/lib/hostess/options.rb +40 -0
- data/lib/hostess/virtual_host.rb +104 -0
- data/lib/hostess.rb +49 -0
- metadata +23 -6
data/README.md
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
Hostess
|
2
|
-
=======
|
1
|
+
# Hostess
|
3
2
|
|
4
3
|
A simple tool for adding local directories as virtual hosts in a local apache installation. It probably only works well on a Mac, but we're scratching our own itch here.
|
5
4
|
|
6
|
-
Usage
|
7
|
-
-----
|
5
|
+
## Usage
|
8
6
|
|
9
|
-
$
|
7
|
+
$ hostess create mysite.local /Users/myuser/Sites/mysite
|
10
8
|
|
11
9
|
This will create a new virtual host in your Apache configuration, setup your Mac's DNS to respond to that domain name, and restart Apache to make the new virtual host live.
|
12
10
|
|
@@ -16,4 +14,3 @@ This will create a new virtual host in your Apache configuration, setup your Mac
|
|
16
14
|
hostess delete domain - delete a virtual host
|
17
15
|
hostess list - list hostess virtual hosts
|
18
16
|
hostess help - this info
|
19
|
-
|
data/Rakefile
CHANGED
@@ -2,10 +2,15 @@ require "rubygems"
|
|
2
2
|
require "rake/gempackagetask"
|
3
3
|
require "rake/rdoctask"
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
require "rake/testtask"
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
9
|
+
t.verbose = true
|
7
10
|
end
|
8
11
|
|
12
|
+
task :default => ["test"]
|
13
|
+
|
9
14
|
# This builds the actual gem. For details of what all these options
|
10
15
|
# mean, and other ones you can add, check the documentation here:
|
11
16
|
#
|
@@ -15,7 +20,7 @@ spec = Gem::Specification.new do |s|
|
|
15
20
|
|
16
21
|
# Change these as appropriate
|
17
22
|
s.name = "hostess"
|
18
|
-
s.version = "0.1.
|
23
|
+
s.version = "0.1.6"
|
19
24
|
s.summary = "Manage simple apache virtual hosts"
|
20
25
|
s.author = "Chris Roos, James Adam"
|
21
26
|
s.email = "chris@chrisroos.co.uk"
|
@@ -28,10 +33,10 @@ spec = Gem::Specification.new do |s|
|
|
28
33
|
s.extra_rdoc_files = %w(README.md)
|
29
34
|
s.rdoc_options = %w(--main README.md)
|
30
35
|
|
31
|
-
s.require_paths = ['bin']
|
36
|
+
s.require_paths = ['bin', 'lib']
|
32
37
|
|
33
38
|
# Add any extra files to include in the gem (like your README)
|
34
|
-
s.files = %w(README.md Rakefile) + Dir.glob("{bin}/**/*")
|
39
|
+
s.files = %w(README.md Rakefile) + Dir.glob("{bin}/**/*") + Dir.glob("{lib}/**/*")
|
35
40
|
s.executables = FileList["bin/**"].map { |f| File.basename(f) }
|
36
41
|
|
37
42
|
# If you want to depend on other gems, add them here, along with any
|
@@ -39,7 +44,7 @@ spec = Gem::Specification.new do |s|
|
|
39
44
|
# s.add_dependency("some_other_gem", "~> 0.1.0")
|
40
45
|
|
41
46
|
# If your tests use any gems, include them here
|
42
|
-
|
47
|
+
s.add_development_dependency("mocha")
|
43
48
|
|
44
49
|
# If you want to publish automatically to rubyforge, you'll may need
|
45
50
|
# to tweak this, and the publishing task below too.
|
data/bin/hostess
CHANGED
@@ -1,144 +1,6 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'fileutils'
|
5
|
-
require 'pathname'
|
6
|
-
|
7
|
-
module Hostess
|
8
|
-
SCRIPT = File.basename($0)
|
9
|
-
APACHE_CONFIG_DIR = Pathname.new('/') + 'etc' + 'apache2'
|
10
|
-
APACHE_CONFIG = APACHE_CONFIG_DIR + 'httpd.conf'
|
11
|
-
VHOSTS_DIR = APACHE_CONFIG_DIR + "#{SCRIPT}_vhosts"
|
12
|
-
class Options
|
13
|
-
attr_reader :action, :domain, :directory
|
14
|
-
def initialize(action=nil, domain=nil, directory=nil)
|
15
|
-
@action, @domain, @directory = action, domain, directory
|
16
|
-
end
|
17
|
-
def directory
|
18
|
-
File.expand_path(@directory) if @directory
|
19
|
-
end
|
20
|
-
def display_banner_and_return
|
21
|
-
puts banner
|
22
|
-
exit
|
23
|
-
end
|
24
|
-
def valid?
|
25
|
-
valid_create? or valid_delete? or valid_list? or valid_help?
|
26
|
-
end
|
27
|
-
private
|
28
|
-
def valid_create?
|
29
|
-
@action == 'create' and domain and directory
|
30
|
-
end
|
31
|
-
def valid_delete?
|
32
|
-
@action == 'delete' and domain
|
33
|
-
end
|
34
|
-
def valid_list?
|
35
|
-
@action == 'list'
|
36
|
-
end
|
37
|
-
def valid_help?
|
38
|
-
@action == 'help'
|
39
|
-
end
|
40
|
-
def banner
|
41
|
-
<<EndBanner
|
42
|
-
Usage:
|
43
|
-
#{SCRIPT} create domain directory - create a new virtual host
|
44
|
-
#{SCRIPT} delete domain - delete a virtual host
|
45
|
-
#{SCRIPT} list - list #{SCRIPT} virtual hosts
|
46
|
-
#{SCRIPT} help - this info
|
47
|
-
EndBanner
|
48
|
-
end
|
49
|
-
end
|
50
|
-
class VirtualHost
|
51
|
-
def initialize(options)
|
52
|
-
@options = options
|
53
|
-
end
|
54
|
-
def execute!
|
55
|
-
__send__(@options.action)
|
56
|
-
end
|
57
|
-
def create
|
58
|
-
warn_and_return unless sudoer?
|
59
|
-
setup_apache_config
|
60
|
-
create_vhost_directory
|
61
|
-
create_apache_log_directory
|
62
|
-
system "dscl localhost -create /Local/Default/Hosts/#{@options.domain} IPAddress 127.0.0.1"
|
63
|
-
File.open(config_filename, 'w') { |f| f.puts(vhost_config) }
|
64
|
-
restart_apache
|
65
|
-
end
|
66
|
-
def delete
|
67
|
-
warn_and_return unless sudoer?
|
68
|
-
system "dscl localhost -delete /Local/Default/Hosts/#{@options.domain}"
|
69
|
-
File.delete(config_filename)
|
70
|
-
restart_apache
|
71
|
-
end
|
72
|
-
def list
|
73
|
-
Dir[File.join(VHOSTS_DIR, '*.conf')].each do |config_file|
|
74
|
-
puts File.basename(config_file, '.conf')
|
75
|
-
end
|
76
|
-
end
|
77
|
-
def help
|
78
|
-
@options.display_banner_and_return
|
79
|
-
end
|
80
|
-
private
|
81
|
-
def apache_log_directory
|
82
|
-
File.expand_path(File.join('~', "." + SCRIPT, 'log', @options.domain))
|
83
|
-
end
|
84
|
-
def create_apache_log_directory
|
85
|
-
FileUtils.mkdir_p(apache_log_directory)
|
86
|
-
end
|
87
|
-
def warn_and_return
|
88
|
-
puts "Please use sudo to use this utility to create or delete virtual hosts"
|
89
|
-
exit
|
90
|
-
end
|
91
|
-
def sudoer?
|
92
|
-
# A proxy for actually knowing whether or not the user has all required privileges
|
93
|
-
File.stat(APACHE_CONFIG).writable?
|
94
|
-
end
|
95
|
-
def vhost_config
|
96
|
-
domain, directory = @options.domain, @options.directory
|
97
|
-
template = <<-EOT
|
98
|
-
<VirtualHost *:80>
|
99
|
-
ServerName <%= domain %>
|
100
|
-
DocumentRoot <%= directory %>
|
101
|
-
<Directory <%= directory %>>
|
102
|
-
Options FollowSymLinks
|
103
|
-
AllowOverride All
|
104
|
-
allow from all
|
105
|
-
</Directory>
|
106
|
-
<DirectoryMatch "^/.*/\.svn/">
|
107
|
-
ErrorDocument 403 /404.html
|
108
|
-
Order allow,deny
|
109
|
-
Deny from all
|
110
|
-
Satisfy All
|
111
|
-
</DirectoryMatch>
|
112
|
-
ErrorLog <%= File.join(apache_log_directory, 'error_log') %>
|
113
|
-
CustomLog <%= File.join(apache_log_directory, 'access_log') %> common
|
114
|
-
#RewriteLogLevel 3
|
115
|
-
RewriteLog <%= File.join(apache_log_directory, 'rewrite_log') %>
|
116
|
-
</VirtualHost>
|
117
|
-
EOT
|
118
|
-
ERB.new(template).result(binding)
|
119
|
-
end
|
120
|
-
def config_filename
|
121
|
-
File.join(VHOSTS_DIR, "#{@options.domain}.conf")
|
122
|
-
end
|
123
|
-
def setup_apache_config
|
124
|
-
unless File.read(APACHE_CONFIG).include?("Include #{File.join(VHOSTS_DIR, '*.conf')}")
|
125
|
-
File.open(APACHE_CONFIG, 'a') do |file|
|
126
|
-
file.puts ""
|
127
|
-
file.puts ""
|
128
|
-
file.puts "# Line added by #{SCRIPT}"
|
129
|
-
file.puts "NameVirtualHost *:80"
|
130
|
-
file.puts "Include #{File.join(VHOSTS_DIR, '*.conf')}"
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
def create_vhost_directory
|
135
|
-
FileUtils.mkdir_p(VHOSTS_DIR)
|
136
|
-
end
|
137
|
-
def restart_apache
|
138
|
-
`apachectl restart`
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
3
|
+
require 'hostess'
|
142
4
|
|
143
5
|
options = Hostess::Options.new(*ARGV)
|
144
6
|
options.display_banner_and_return unless options.valid?
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Hostess
|
2
|
+
class Options
|
3
|
+
attr_reader :action, :domain, :directory
|
4
|
+
def initialize(action=nil, domain=nil, directory=nil)
|
5
|
+
@action, @domain, @directory = action, domain, directory
|
6
|
+
end
|
7
|
+
def directory
|
8
|
+
File.expand_path(@directory) if @directory
|
9
|
+
end
|
10
|
+
def display_banner_and_return
|
11
|
+
puts banner
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
def valid?
|
15
|
+
valid_create? or valid_delete? or valid_list? or valid_help?
|
16
|
+
end
|
17
|
+
private
|
18
|
+
def valid_create?
|
19
|
+
@action == 'create' and domain and directory
|
20
|
+
end
|
21
|
+
def valid_delete?
|
22
|
+
@action == 'delete' and domain
|
23
|
+
end
|
24
|
+
def valid_list?
|
25
|
+
@action == 'list'
|
26
|
+
end
|
27
|
+
def valid_help?
|
28
|
+
@action == 'help'
|
29
|
+
end
|
30
|
+
def banner
|
31
|
+
<<EndBanner
|
32
|
+
Usage:
|
33
|
+
#{Hostess.script_name} create domain directory - create a new virtual host
|
34
|
+
#{Hostess.script_name} delete domain - delete a virtual host
|
35
|
+
#{Hostess.script_name} list - list #{Hostess.script_name} virtual hosts
|
36
|
+
#{Hostess.script_name} help - this info
|
37
|
+
EndBanner
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Hostess
|
2
|
+
class VirtualHost
|
3
|
+
def initialize(options, debug=false)
|
4
|
+
@options, @debug = options, debug
|
5
|
+
end
|
6
|
+
def execute!
|
7
|
+
__send__(@options.action)
|
8
|
+
end
|
9
|
+
def create
|
10
|
+
setup_apache_config
|
11
|
+
create_vhost_directory
|
12
|
+
create_apache_log_directory
|
13
|
+
create_dns_entry
|
14
|
+
create_vhost
|
15
|
+
restart_apache
|
16
|
+
end
|
17
|
+
def delete
|
18
|
+
delete_dns_entry
|
19
|
+
delete_vhost
|
20
|
+
restart_apache
|
21
|
+
end
|
22
|
+
def list
|
23
|
+
Dir[File.join(Hostess.vhosts_dir, '*.conf')].each do |config_file|
|
24
|
+
puts File.basename(config_file, '.conf')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
def help
|
28
|
+
@options.display_banner_and_return
|
29
|
+
end
|
30
|
+
private
|
31
|
+
def create_dns_entry
|
32
|
+
run "dscl localhost -create /Local/Default/Hosts/#{@options.domain} IPAddress 127.0.0.1"
|
33
|
+
end
|
34
|
+
def delete_dns_entry
|
35
|
+
run "dscl localhost -delete /Local/Default/Hosts/#{@options.domain}"
|
36
|
+
end
|
37
|
+
def create_vhost
|
38
|
+
tempfile = Tempfile.new('vhost')
|
39
|
+
tempfile.puts(vhost_config)
|
40
|
+
tempfile.close
|
41
|
+
run "mv #{tempfile.path} #{config_filename}"
|
42
|
+
end
|
43
|
+
def delete_vhost
|
44
|
+
run "rm #{config_filename}"
|
45
|
+
end
|
46
|
+
def apache_log_directory
|
47
|
+
File.join(Hostess.vhosts_log_dir, @options.domain)
|
48
|
+
end
|
49
|
+
def create_apache_log_directory
|
50
|
+
run "mkdir -p #{apache_log_directory}"
|
51
|
+
end
|
52
|
+
def vhost_config
|
53
|
+
domain, directory = @options.domain, @options.directory
|
54
|
+
template = <<-EOT
|
55
|
+
<VirtualHost *:80>
|
56
|
+
ServerName <%= domain %>
|
57
|
+
DocumentRoot <%= directory %>
|
58
|
+
<Directory <%= directory %>>
|
59
|
+
Options FollowSymLinks
|
60
|
+
AllowOverride All
|
61
|
+
allow from all
|
62
|
+
</Directory>
|
63
|
+
<DirectoryMatch "^/.*/\.svn/">
|
64
|
+
ErrorDocument 403 /404.html
|
65
|
+
Order allow,deny
|
66
|
+
Deny from all
|
67
|
+
Satisfy All
|
68
|
+
</DirectoryMatch>
|
69
|
+
ErrorLog <%= File.join(apache_log_directory, 'error_log') %>
|
70
|
+
CustomLog <%= File.join(apache_log_directory, 'access_log') %> common
|
71
|
+
#RewriteLogLevel 3
|
72
|
+
RewriteLog <%= File.join(apache_log_directory, 'rewrite_log') %>
|
73
|
+
</VirtualHost>
|
74
|
+
EOT
|
75
|
+
ERB.new(template).result(binding)
|
76
|
+
end
|
77
|
+
def config_filename
|
78
|
+
File.join(Hostess.vhosts_dir, "#{@options.domain}.conf")
|
79
|
+
end
|
80
|
+
def setup_apache_config
|
81
|
+
unless File.read(Hostess.apache_config).include?("Include #{File.join(Hostess.vhosts_dir, '*.conf')}")
|
82
|
+
run "echo '' >> #{Hostess.apache_config}"
|
83
|
+
run "echo '' >> #{Hostess.apache_config}"
|
84
|
+
run "echo '# Line added by #{Hostess.script_name}' >> #{Hostess.apache_config}"
|
85
|
+
run "echo 'NameVirtualHost *:80' >> #{Hostess.apache_config}"
|
86
|
+
run "echo 'Include #{File.join(Hostess.vhosts_dir, '*.conf')}' >> #{Hostess.apache_config}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
def create_vhost_directory
|
90
|
+
run "mkdir -p #{Hostess.vhosts_dir}"
|
91
|
+
end
|
92
|
+
def restart_apache
|
93
|
+
run "apachectl restart"
|
94
|
+
end
|
95
|
+
def run(cmd)
|
96
|
+
cmd = sudo(cmd) if Hostess.use_sudo?
|
97
|
+
puts cmd if @debug
|
98
|
+
system cmd
|
99
|
+
end
|
100
|
+
def sudo(cmd)
|
101
|
+
"sudo -s \"#{cmd}\""
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/hostess.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'pathname'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
module Hostess
|
7
|
+
|
8
|
+
autoload :Options, 'hostess/options'
|
9
|
+
autoload :VirtualHost, 'hostess/virtual_host'
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
attr_writer :apache_config_dir, :apache_log_dir
|
14
|
+
|
15
|
+
def script_name
|
16
|
+
'hostess'
|
17
|
+
end
|
18
|
+
|
19
|
+
def apache_config_dir
|
20
|
+
@apache_config_dir || File.join('/', 'etc', 'apache2')
|
21
|
+
end
|
22
|
+
|
23
|
+
def apache_config
|
24
|
+
File.join(apache_config_dir, 'httpd.conf')
|
25
|
+
end
|
26
|
+
|
27
|
+
def vhosts_dir
|
28
|
+
File.join(apache_config_dir, "#{script_name}_vhosts")
|
29
|
+
end
|
30
|
+
|
31
|
+
def apache_log_dir
|
32
|
+
@apache_log_dir || File.join('/', 'var', 'log', 'apache2')
|
33
|
+
end
|
34
|
+
|
35
|
+
def vhosts_log_dir
|
36
|
+
File.join(apache_log_dir, "#{script_name}_vhosts")
|
37
|
+
end
|
38
|
+
|
39
|
+
def disable_sudo!
|
40
|
+
@disable_sudo = true
|
41
|
+
end
|
42
|
+
|
43
|
+
def use_sudo?
|
44
|
+
@disable_sudo ? false : true
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hostess
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 6
|
10
|
+
version: 0.1.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Chris Roos, James Adam
|
@@ -15,10 +15,23 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-26 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: mocha
|
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: :development
|
34
|
+
version_requirements: *id001
|
22
35
|
description:
|
23
36
|
email: chris@chrisroos.co.uk
|
24
37
|
executables:
|
@@ -31,6 +44,9 @@ files:
|
|
31
44
|
- README.md
|
32
45
|
- Rakefile
|
33
46
|
- bin/hostess
|
47
|
+
- lib/hostess/options.rb
|
48
|
+
- lib/hostess/virtual_host.rb
|
49
|
+
- lib/hostess.rb
|
34
50
|
has_rdoc: false
|
35
51
|
homepage: http://chrisroos.co.uk
|
36
52
|
licenses: []
|
@@ -41,6 +57,7 @@ rdoc_options:
|
|
41
57
|
- README.md
|
42
58
|
require_paths:
|
43
59
|
- bin
|
60
|
+
- lib
|
44
61
|
required_ruby_version: !ruby/object:Gem::Requirement
|
45
62
|
none: false
|
46
63
|
requirements:
|