symbiosis-create-sites 6.76 KB
Newer Older
1
#!/usr/bin/ruby1.8
2
3
4
#
# NAME
#
5
#  symbiosis-create-sites -- Auto-configure Apache2 sites with specified IPs
6
#
7
8
9
10
11
12
13
14
# SYNOPSIS
#
#  symbiosis-create-sites [ --ssl-template | -s <file> ] 
#                         [ --non-ssl-template | -t <file> ] 
#                         [ --apache2-dir | -a <directory> ] 
#                         [ --force | -f ] [ --no-restart | -r ]
#                         [ --help | -h ] [ --manual | -m ] [ --verbose | -v ]
#
15
# OPTIONS
16
#
17
18
19
# --ssl-template, -s <file>      Specify the template file for SSL sites.
#                                Defaults to
#                                /etc/symbiosis/apache.d/non_ssl.template.erb
20
#
21
22
23
# --non-ssl-template, -t <file>  Specify the template file for non-SSL sites.
#                                Defaults to
#                                /etc/symbiosis/apache.d/non_ssl.template.erb
24
#
25
26
27
# --apache2-dir, -a <directory>  Specify the location of the apache2
#                                configuration directory. Defaults to
#                                /etc/apache2.
28
#
29
# --force, -f       Force the re-creation of all sites.
30
#
31
32
# --no-restart, -r  Do not restart apache2 even if changes have taken place.
#
33
34
35
# --manual, -m      Show the manual for this script.
#
# --help, -h        Show brief usage instructions for this script.
36
37
38
39
#
# --verbose, -v     Show debugging information.
#
# USAGE
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#
#   This script is designed to iterate over the domains hosted
#  upon a Symbiosis system, and configure Apache to listen appropriate
#  when a domain is configured for SSL hosting and not yet configured.
#
# AUTHOR
#
#   Steve Kemp <steve@bytemark.co.uk>
#


require 'getoptlong'

#
#  Entry point to the code
#
$FORCE    = false
$VERBOSE  = false
58
59
help      = false
manual    = false
60

61
62
63
64
#
#  Do we need to restart apache?
#
$RESTART=false
65
66
67
68
69
70
71
72

#
# The root directory -- '/' by default.
#
root = "/"
non_ssl_template = nil 
ssl_template     = nil 
apache2_dir      = nil
73
no_restart       = false
74
75

opts = GetoptLong.new(
76
         [ '--help',             '-h', GetoptLong::NO_ARGUMENT ],
77
         [ '--manual',           '-m', GetoptLong::NO_ARGUMENT ],
78
79
80
81
82
83
84
         [ '--verbose',          '-v', GetoptLong::NO_ARGUMENT ],
         [ '--force',            '-f', GetoptLong::NO_ARGUMENT ],
         [ '--no-restart',       '-n', GetoptLong::NO_ARGUMENT],
         [ '--ssl-template',     '-s', GetoptLong::REQUIRED_ARGUMENT ],
         [ '--non-ssl-template', '-t', GetoptLong::REQUIRED_ARGUMENT ],
         [ '--apache2-dir',      '-a', GetoptLong::REQUIRED_ARGUMENT ],
         [ '--root-dir',         '-r', GetoptLong::REQUIRED_ARGUMENT ]
85
86
87
88
       )

opts.each do |opt, arg|
  case opt
89
90
91
92
93
94
95
96
  when '--ssl-template'
    ssl_template = arg
  when '--non-ssl-template'
    non_ssl_template = arg
  when '--apache2-dir'
    apache2_dir = arg
  when '--root'
    root = arg
97
98
99
  when '--no-restart'
    no_restart = true
  when '--help'
100
101
102
    help = true
  when '--manual'
    manual = true
103
104
  when '--verbose'
    $VERBOSE = true
105
106
107
108
109
110
111
112
  when '--force'
    $FORCE = true
  end
end

#
# CAUTION! Here be quality kode.
#
113
114
if manual or help

115
  # Open the file, stripping the shebang line
116
117
118
  lines = File.open(__FILE__){|fh| fh.readlines}[1..-1]

  found_synopsis = false
119
120

  lines.each do |line|
121

122
123
    line.chomp!
    break if line.empty?
124
125
126
127
128
129

    if help and !found_synopsis
      found_synopsis = (line =~ /^#\s+SYNOPSIS\s*$/)
      next
    end

130
    puts line[2..-1].to_s
131
132
133

    break if help and found_synopsis and line =~ /^#\s*$/

134
135
136
137
138
139
140
141
142
  end

  exit 0
end

def verbose(s)
  puts s if $VERBOSE
end

143
144
145
146
147
148
#
# Requirements after the help clause has finished.
#
require 'erb'
require 'symbiosis/domains'
require 'symbiosis/domain/ssl'
149
require 'symbiosis/config_files/apache'
150

151
152
153
154
155
156
157
158
159
160
161
162
163
#
# Set the default paths.
#
non_ssl_template = File.join(root, "/etc/symbiosis/apache.d/non_ssl.template.erb") if non_ssl_template.nil?
ssl_template     = File.join(root, "/etc/symbiosis/apache.d/ssl.template.erb") if ssl_template.nil?
apache2_dir      = File.join(root, "/etc/apache2") if apache2_dir.nil?

#
# Any arguments on the command line specify which domains to do.
#
domains_to_configure = ARGV

primary_ips = [Symbiosis::Host.primary_ipv4, Symbiosis::Host.primary_ipv6]
164

165
166
167
#
#  For each domain.
#
168
Symbiosis::Domains.each do |domain|
169

170
  verbose "Domain: #{domain.name} "
171

172
173
  next unless domains_to_configure.empty? or domains_to_configure.include?(domain.name)

174
175
176
177
178
  if domain.is_alias?
    verbose "\tSkipping as #{domain.symlink} is a link to #{domain.directory}."
    next
  end

179
180
  begin
    sites_available_file = File.join(apache2_dir, "sites-available","#{domain.name}.conf")
181
    sites_enabled_file   = File.join(apache2_dir, "sites-enabled","#{domain.name}.conf")
182

183
    config        = Symbiosis::ConfigFiles::Apache.new(sites_available_file, "#")
184
    config.domain = domain
185

186
187
188
189
    if domain.ips.any?{|ip| primary_ips.include?(ip)}
      verbose "\tNot configuring this site, as it is using at least one of this host's primary IPs."
      next
    end
190

191
192
193
194
195
    #
    #  If SSL is not enabled then we can skip
    #
    if ( domain.ssl_enabled? )
      config.template = ssl_template
196

197
198
199
200
201
202
      verbose "\tSSL is enabled -- using SSL template"
    else
      config.template = non_ssl_template
    
      verbose "\tSSL is not enabled -- using non-SSL template"
    end
203
204
205
206
207
208
209
210
211
212
213
214

    #
    #  If there is already a site enabled we only
    # need to touch it if one of the SSL-files is more
    # recent than the generated file.
    #
    #  e.g. User adds /config/ssl.combined and a site
    # is generated but broken because a mandatory bundle is missing.
    #


    if ( $FORCE )
215
      verbose "\tForcing re-creation of configuration due to --force."
216

217
    elsif config.exists?
218

219
      if config.changed?
220
        verbose "\tNot updating configuration, as it has been edited by hand."
221
222
        next

223
      elsif config.outdated?
224
        verbose "\tRe-creating configuration as it is out of date."
225
226
227
228
229
230
231
232
233
234

      else
        verbose "\tSite already present and up-to date."
        next

      end

    else
      verbose "\tConfiguring site for the first time"

235
      end
236

237
238
239
240
    #
    # This gets apache2 to check the configuration using a temporary file.
    #
    if config.ok?
241

242
243
      verbose "\tWriting configuration"
      config.write
244
245
246
      
      # Definitely restart if we've rewritten the config.
      $RESTART = true
247

248
      unless config.enabled?(sites_enabled_file)
249
        verbose "\tEnabling site"
250
        config.enable(sites_enabled_file, $FORCE)
251
      end
252
253

    else
254
      verbose "\tApache has rejected the new configuration -- no changes have been made."
255
256
    end

257
258
259
260
261
262
    #
    # Rescue errors for this domain, but continue for others.
    #
  rescue StandardError => err
    warn "\tUnable to configure site for #{domain.name} because #{err.to_s}"
    verbose "\t"+err.backtrace.join("\n\t")
263
264
265
266
267
268
  end
end

#
#  All done.
#
269
if ( $RESTART and !no_restart )
270
271
272
273
  verbose "Restarting Apache"

  system( "/etc/init.d/apache2 restart" )
end