hostess 0.1.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/README +11 -0
- data/Rakefile +114 -0
- data/bin/hostess +145 -0
- metadata +58 -0
data/README
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Hostess
|
2
|
+
=======
|
3
|
+
|
4
|
+
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
|
+
|
6
|
+
Usage
|
7
|
+
-----
|
8
|
+
|
9
|
+
$ sudo hostess create mysite.local /Users/myuser/Sites/mysite
|
10
|
+
|
11
|
+
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.
|
data/Rakefile
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake/gempackagetask"
|
3
|
+
require "rake/rdoctask"
|
4
|
+
|
5
|
+
task :default => :package do
|
6
|
+
puts "Don't forget to write some tests!"
|
7
|
+
end
|
8
|
+
|
9
|
+
# This builds the actual gem. For details of what all these options
|
10
|
+
# mean, and other ones you can add, check the documentation here:
|
11
|
+
#
|
12
|
+
# http://rubygems.org/read/chapter/20
|
13
|
+
#
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
|
16
|
+
# Change these as appropriate
|
17
|
+
s.name = "hostess"
|
18
|
+
s.version = "0.1.1"
|
19
|
+
s.summary = "Manage simple apache virtual hosts"
|
20
|
+
s.author = "Chris Roos, James Adam"
|
21
|
+
s.email = "chris@chrisroos.co.uk"
|
22
|
+
s.homepage = "http://chrisroos.co.uk"
|
23
|
+
|
24
|
+
s.has_rdoc = false
|
25
|
+
|
26
|
+
# You should probably have a README of some kind. Change the filename
|
27
|
+
# as appropriate
|
28
|
+
s.extra_rdoc_files = %w(README)
|
29
|
+
s.rdoc_options = %w(--main README)
|
30
|
+
|
31
|
+
s.require_paths = ['bin']
|
32
|
+
|
33
|
+
# Add any extra files to include in the gem (like your README)
|
34
|
+
s.files = %w(README Rakefile) + Dir.glob("{bin}/**/*")
|
35
|
+
s.executables = FileList["bin/**"].map { |f| File.basename(f) }
|
36
|
+
|
37
|
+
# If you want to depend on other gems, add them here, along with any
|
38
|
+
# relevant versions
|
39
|
+
# s.add_dependency("some_other_gem", "~> 0.1.0")
|
40
|
+
|
41
|
+
# If your tests use any gems, include them here
|
42
|
+
# s.add_development_dependency("mocha")
|
43
|
+
|
44
|
+
# If you want to publish automatically to rubyforge, you'll may need
|
45
|
+
# to tweak this, and the publishing task below too.
|
46
|
+
s.rubyforge_project = "hostess"
|
47
|
+
end
|
48
|
+
|
49
|
+
# This task actually builds the gem. We also regenerate a static
|
50
|
+
# .gemspec file, which is useful if something (i.e. GitHub) will
|
51
|
+
# be automatically building a gem for this project. If you're not
|
52
|
+
# using GitHub, edit as appropriate.
|
53
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
54
|
+
pkg.gem_spec = spec
|
55
|
+
|
56
|
+
# Generate the gemspec file for github.
|
57
|
+
file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
|
58
|
+
File.open(file, "w") {|f| f << spec.to_ruby }
|
59
|
+
end
|
60
|
+
|
61
|
+
# Generate documentation
|
62
|
+
Rake::RDocTask.new do |rd|
|
63
|
+
|
64
|
+
rd.rdoc_files.include("lib/**/*.rb")
|
65
|
+
rd.rdoc_dir = "rdoc"
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Clear out RDoc and generated packages'
|
69
|
+
task :clean => [:clobber_rdoc, :clobber_package] do
|
70
|
+
rm "#{spec.name}.gemspec"
|
71
|
+
end
|
72
|
+
|
73
|
+
# If you want to publish to RubyForge automatically, here's a simple
|
74
|
+
# task to help do that. If you don't, just get rid of this.
|
75
|
+
# Be sure to set up your Rubyforge account details with the Rubyforge
|
76
|
+
# gem; you'll need to run `rubyforge setup` and `rubyforge config` at
|
77
|
+
# the very least.
|
78
|
+
begin
|
79
|
+
require "rake/contrib/sshpublisher"
|
80
|
+
namespace :rubyforge do
|
81
|
+
|
82
|
+
desc "Release gem and RDoc documentation to RubyForge"
|
83
|
+
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
84
|
+
|
85
|
+
namespace :release do
|
86
|
+
desc "Release a new version of this gem"
|
87
|
+
task :gem => [:package] do
|
88
|
+
require 'rubyforge'
|
89
|
+
rubyforge = RubyForge.new
|
90
|
+
rubyforge.configure
|
91
|
+
rubyforge.login
|
92
|
+
rubyforge.userconfig['release_notes'] = spec.summary
|
93
|
+
path_to_gem = File.join(File.dirname(__FILE__), "pkg", "#{spec.name}-#{spec.version}.gem")
|
94
|
+
puts "Publishing #{spec.name}-#{spec.version.to_s} to Rubyforge..."
|
95
|
+
rubyforge.add_release(spec.rubyforge_project, spec.name, spec.version.to_s, path_to_gem)
|
96
|
+
end
|
97
|
+
|
98
|
+
desc "Publish RDoc to RubyForge."
|
99
|
+
task :docs => [:rdoc] do
|
100
|
+
config = YAML.load(
|
101
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
102
|
+
)
|
103
|
+
|
104
|
+
host = "#{config['username']}@rubyforge.org"
|
105
|
+
remote_dir = "/var/www/gforge-projects/hostess/" # Should be the same as the rubyforge project name
|
106
|
+
local_dir = 'rdoc'
|
107
|
+
|
108
|
+
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
rescue LoadError
|
113
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
114
|
+
end
|
data/bin/hostess
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'erb'
|
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('~', 'tmp', 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
|
+
AllowOverride All
|
103
|
+
allow from all
|
104
|
+
</Directory>
|
105
|
+
<DirectoryMatch "^/.*/\.svn/">
|
106
|
+
ErrorDocument 403 /404.html
|
107
|
+
Order allow,deny
|
108
|
+
Deny from all
|
109
|
+
Satisfy All
|
110
|
+
</DirectoryMatch>
|
111
|
+
ErrorLog <%= File.join(apache_log_directory, 'error_log') %>
|
112
|
+
CustomLog <%= File.join(apache_log_directory, 'access_log') %> common
|
113
|
+
#RewriteLogLevel 3
|
114
|
+
RewriteLog <%= File.join(apache_log_directory, 'rewrite_log') %>
|
115
|
+
</VirtualHost>
|
116
|
+
EOT
|
117
|
+
ERB.new(template).result(binding)
|
118
|
+
end
|
119
|
+
def config_filename
|
120
|
+
File.join(VHOSTS_DIR, "#{@options.domain}.conf")
|
121
|
+
end
|
122
|
+
def setup_apache_config
|
123
|
+
unless File.read(APACHE_CONFIG).include?("Include #{File.join(VHOSTS_DIR, '*.conf')}")
|
124
|
+
File.open(APACHE_CONFIG, 'a') do |file|
|
125
|
+
file.puts ""
|
126
|
+
file.puts ""
|
127
|
+
file.puts "# Line added by #{SCRIPT}"
|
128
|
+
file.puts "NameVirtualHost *:80"
|
129
|
+
file.puts "Include #{File.join(VHOSTS_DIR, '*.conf')}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
def create_vhost_directory
|
134
|
+
FileUtils.mkdir_p(VHOSTS_DIR)
|
135
|
+
end
|
136
|
+
def restart_apache
|
137
|
+
`apachectl restart`
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
options = Hostess::Options.new(*ARGV)
|
143
|
+
options.display_banner_and_return unless options.valid?
|
144
|
+
|
145
|
+
Hostess::VirtualHost.new(options).execute!
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hostess
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Roos, James Adam
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-15 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: chris@chrisroos.co.uk
|
18
|
+
executables:
|
19
|
+
- hostess
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- README
|
26
|
+
- Rakefile
|
27
|
+
- bin/hostess
|
28
|
+
has_rdoc: true
|
29
|
+
homepage: http://chrisroos.co.uk
|
30
|
+
licenses: []
|
31
|
+
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options:
|
34
|
+
- --main
|
35
|
+
- README
|
36
|
+
require_paths:
|
37
|
+
- bin
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: "0"
|
43
|
+
version:
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
requirements: []
|
51
|
+
|
52
|
+
rubyforge_project: hostess
|
53
|
+
rubygems_version: 1.3.3
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: Manage simple apache virtual hosts
|
57
|
+
test_files: []
|
58
|
+
|