capistrano 2.1.0 → 3.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +89 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +674 -0
- data/README.md +226 -0
- data/Rakefile +5 -0
- data/bin/cap +2 -3
- data/bin/capify +7 -77
- data/capistrano-public_cert.pem +22 -0
- data/capistrano.gemspec +35 -0
- data/features/deploy.feature +52 -0
- data/features/installation.feature +16 -0
- data/features/remote_file_task.feature +14 -0
- data/features/step_definitions/assertions.rb +90 -0
- data/features/step_definitions/cap_commands.rb +8 -0
- data/features/step_definitions/setup.rb +25 -0
- data/features/support/env.rb +12 -0
- data/features/support/remote_command_helpers.rb +20 -0
- data/lib/Capfile +3 -0
- data/lib/capistrano/all.rb +16 -0
- data/lib/capistrano/application.rb +60 -0
- data/lib/capistrano/configuration/question.rb +42 -0
- data/lib/capistrano/configuration/server.rb +133 -0
- data/lib/capistrano/configuration/servers/role_filter.rb +86 -0
- data/lib/capistrano/configuration/servers.rb +53 -58
- data/lib/capistrano/configuration.rb +84 -30
- data/lib/capistrano/console.rb +1 -0
- data/lib/capistrano/defaults.rb +13 -0
- data/lib/capistrano/deploy.rb +3 -0
- data/lib/capistrano/dotfile.rb +3 -0
- data/lib/capistrano/dsl/env.rb +64 -0
- data/lib/capistrano/dsl/paths.rb +94 -0
- data/lib/capistrano/dsl/stages.rb +15 -0
- data/lib/capistrano/dsl/task_enhancements.rb +53 -0
- data/lib/capistrano/dsl.rb +48 -0
- data/lib/capistrano/git.rb +1 -0
- data/lib/capistrano/hg.rb +1 -0
- data/lib/capistrano/i18n.rb +34 -0
- data/lib/capistrano/install.rb +1 -0
- data/lib/capistrano/setup.rb +21 -0
- data/lib/capistrano/tasks/console.rake +21 -0
- data/lib/capistrano/tasks/deploy.rake +204 -0
- data/lib/capistrano/tasks/framework.rake +67 -0
- data/lib/capistrano/tasks/git.rake +62 -0
- data/lib/capistrano/tasks/hg.rake +39 -0
- data/lib/capistrano/tasks/install.rake +39 -0
- data/lib/capistrano/templates/Capfile +26 -0
- data/lib/capistrano/templates/deploy.rb.erb +40 -0
- data/lib/capistrano/templates/stage.rb.erb +42 -0
- data/lib/capistrano/version.rb +1 -20
- data/lib/capistrano/version_validator.rb +37 -0
- data/lib/capistrano.rb +0 -2
- data/spec/integration/dsl_spec.rb +344 -0
- data/spec/integration_spec_helper.rb +7 -0
- data/spec/lib/capistrano/application_spec.rb +61 -0
- data/spec/lib/capistrano/configuration/question_spec.rb +54 -0
- data/spec/lib/capistrano/configuration/server_spec.rb +249 -0
- data/spec/lib/capistrano/configuration/servers/role_filter_spec.rb +140 -0
- data/spec/lib/capistrano/configuration/servers_spec.rb +184 -0
- data/spec/lib/capistrano/configuration_spec.rb +101 -0
- data/spec/lib/capistrano/dsl/env_spec.rb +10 -0
- data/spec/lib/capistrano/dsl/paths_spec.rb +69 -0
- data/spec/lib/capistrano/dsl_spec.rb +63 -0
- data/spec/lib/capistrano/version_validator_spec.rb +103 -0
- data/spec/lib/capistrano_spec.rb +8 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/.gitignore +1 -0
- data/spec/support/Vagrantfile +13 -0
- data/spec/support/matchers.rb +5 -0
- data/spec/support/tasks/database.cap +11 -0
- data/spec/support/test_app.rb +138 -0
- metadata +251 -179
- data/CHANGELOG +0 -512
- data/MIT-LICENSE +0 -20
- data/README +0 -43
- data/examples/sample.rb +0 -14
- data/lib/capistrano/callback.rb +0 -45
- data/lib/capistrano/cli/execute.rb +0 -82
- data/lib/capistrano/cli/help.rb +0 -102
- data/lib/capistrano/cli/help.txt +0 -53
- data/lib/capistrano/cli/options.rb +0 -183
- data/lib/capistrano/cli/ui.rb +0 -28
- data/lib/capistrano/cli.rb +0 -47
- data/lib/capistrano/command.rb +0 -161
- data/lib/capistrano/configuration/actions/file_transfer.rb +0 -35
- data/lib/capistrano/configuration/actions/inspect.rb +0 -46
- data/lib/capistrano/configuration/actions/invocation.rb +0 -134
- data/lib/capistrano/configuration/callbacks.rb +0 -148
- data/lib/capistrano/configuration/connections.rb +0 -159
- data/lib/capistrano/configuration/execution.rb +0 -126
- data/lib/capistrano/configuration/loading.rb +0 -198
- data/lib/capistrano/configuration/namespaces.rb +0 -196
- data/lib/capistrano/configuration/roles.rb +0 -51
- data/lib/capistrano/configuration/variables.rb +0 -127
- data/lib/capistrano/errors.rb +0 -15
- data/lib/capistrano/extensions.rb +0 -57
- data/lib/capistrano/gateway.rb +0 -131
- data/lib/capistrano/logger.rb +0 -59
- data/lib/capistrano/recipes/compat.rb +0 -32
- data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
- data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -46
- data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -96
- data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
- data/lib/capistrano/recipes/deploy/scm/base.rb +0 -192
- data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
- data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -151
- data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -85
- data/lib/capistrano/recipes/deploy/scm/git.rb +0 -191
- data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -129
- data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -126
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -114
- data/lib/capistrano/recipes/deploy/scm.rb +0 -19
- data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -64
- data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -144
- data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
- data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
- data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -47
- data/lib/capistrano/recipes/deploy/strategy.rb +0 -19
- data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/deploy.rb +0 -494
- data/lib/capistrano/recipes/standard.rb +0 -37
- data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/upgrade.rb +0 -33
- data/lib/capistrano/server_definition.rb +0 -51
- data/lib/capistrano/shell.rb +0 -256
- data/lib/capistrano/ssh.rb +0 -109
- data/lib/capistrano/task_definition.rb +0 -69
- data/lib/capistrano/upload.rb +0 -146
- data/test/cli/execute_test.rb +0 -132
- data/test/cli/help_test.rb +0 -139
- data/test/cli/options_test.rb +0 -226
- data/test/cli/ui_test.rb +0 -28
- data/test/cli_test.rb +0 -17
- data/test/command_test.rb +0 -309
- data/test/configuration/actions/file_transfer_test.rb +0 -40
- data/test/configuration/actions/inspect_test.rb +0 -62
- data/test/configuration/actions/invocation_test.rb +0 -202
- data/test/configuration/callbacks_test.rb +0 -206
- data/test/configuration/connections_test.rb +0 -288
- data/test/configuration/execution_test.rb +0 -159
- data/test/configuration/loading_test.rb +0 -127
- data/test/configuration/namespace_dsl_test.rb +0 -297
- data/test/configuration/roles_test.rb +0 -47
- data/test/configuration/servers_test.rb +0 -90
- data/test/configuration/variables_test.rb +0 -180
- data/test/configuration_test.rb +0 -81
- data/test/deploy/scm/accurev_test.rb +0 -23
- data/test/deploy/scm/base_test.rb +0 -55
- data/test/deploy/scm/git_test.rb +0 -112
- data/test/deploy/strategy/copy_test.rb +0 -147
- data/test/extensions_test.rb +0 -69
- data/test/fixtures/cli_integration.rb +0 -5
- data/test/fixtures/config.rb +0 -5
- data/test/fixtures/custom.rb +0 -3
- data/test/gateway_test.rb +0 -167
- data/test/logger_test.rb +0 -123
- data/test/server_definition_test.rb +0 -108
- data/test/shell_test.rb +0 -64
- data/test/ssh_test.rb +0 -97
- data/test/task_definition_test.rb +0 -101
- data/test/upload_test.rb +0 -131
- data/test/utils.rb +0 -42
- data/test/version_test.rb +0 -24
@@ -1,144 +0,0 @@
|
|
1
|
-
require 'capistrano/recipes/deploy/strategy/base'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'tempfile' # Dir.tmpdir
|
4
|
-
|
5
|
-
module Capistrano
|
6
|
-
module Deploy
|
7
|
-
module Strategy
|
8
|
-
|
9
|
-
# This class implements the strategy for deployments which work
|
10
|
-
# by preparing the source code locally, compressing it, copying the
|
11
|
-
# file to each target host, and uncompressing it to the deployment
|
12
|
-
# directory.
|
13
|
-
#
|
14
|
-
# By default, the SCM checkout command is used to obtain the local copy
|
15
|
-
# of the source code. If you would rather use the export operation,
|
16
|
-
# you can set the :copy_strategy variable to :export.
|
17
|
-
#
|
18
|
-
# This deployment strategy supports a special variable,
|
19
|
-
# :copy_compression, which must be one of :gzip, :bz2, or
|
20
|
-
# :zip, and which specifies how the source should be compressed for
|
21
|
-
# transmission to each host.
|
22
|
-
class Copy < Base
|
23
|
-
# Obtains a copy of the source code locally (via the #command method),
|
24
|
-
# compresses it to a single file, copies that file to all target
|
25
|
-
# servers, and uncompresses it on each of them into the deployment
|
26
|
-
# directory.
|
27
|
-
def deploy!
|
28
|
-
logger.debug "getting (via #{copy_strategy}) revision #{revision} to #{destination}"
|
29
|
-
system(command)
|
30
|
-
File.open(File.join(destination, "REVISION"), "w") { |f| f.puts(revision) }
|
31
|
-
|
32
|
-
logger.trace "compressing #{destination} to #{filename}"
|
33
|
-
Dir.chdir(tmpdir) { system(compress(File.basename(destination), File.basename(filename)).join(" ")) }
|
34
|
-
|
35
|
-
content = File.open(filename, "rb") { |f| f.read }
|
36
|
-
put content, remote_filename
|
37
|
-
run "cd #{configuration[:releases_path]} && #{decompress(remote_filename).join(" ")} && rm #{remote_filename}"
|
38
|
-
ensure
|
39
|
-
FileUtils.rm filename rescue nil
|
40
|
-
FileUtils.rm_rf destination rescue nil
|
41
|
-
end
|
42
|
-
|
43
|
-
def check!
|
44
|
-
super.check do |d|
|
45
|
-
d.local.command(source.local.command)
|
46
|
-
d.local.command(compress(nil, nil).first)
|
47
|
-
d.remote.command(decompress(nil).first)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
# Returns the basename of the release_path, which will be used to
|
54
|
-
# name the local copy and archive file.
|
55
|
-
def destination
|
56
|
-
@destination ||= File.join(tmpdir, File.basename(configuration[:release_path]))
|
57
|
-
end
|
58
|
-
|
59
|
-
# Returns the value of the :copy_strategy variable, defaulting to
|
60
|
-
# :checkout if it has not been set.
|
61
|
-
def copy_strategy
|
62
|
-
@copy_strategy ||= configuration.fetch(:copy_strategy, :checkout)
|
63
|
-
end
|
64
|
-
|
65
|
-
# Should return the command(s) necessary to obtain the source code
|
66
|
-
# locally.
|
67
|
-
def command
|
68
|
-
@command ||= case copy_strategy
|
69
|
-
when :checkout
|
70
|
-
source.checkout(revision, destination)
|
71
|
-
when :export
|
72
|
-
source.export(revision, destination)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Returns the name of the file that the source code will be
|
77
|
-
# compressed to.
|
78
|
-
def filename
|
79
|
-
@filename ||= File.join(tmpdir, "#{File.basename(destination)}.#{compression_extension}")
|
80
|
-
end
|
81
|
-
|
82
|
-
# The directory to which the copy should be checked out
|
83
|
-
def tmpdir
|
84
|
-
@tmpdir ||= configuration[:copy_dir] || Dir.tmpdir
|
85
|
-
end
|
86
|
-
|
87
|
-
# The directory on the remote server to which the archive should be
|
88
|
-
# copied
|
89
|
-
def remote_dir
|
90
|
-
@remote_dir ||= configuration[:copy_remote_dir] || "/tmp"
|
91
|
-
end
|
92
|
-
|
93
|
-
# The location on the remote server where the file should be
|
94
|
-
# temporarily stored.
|
95
|
-
def remote_filename
|
96
|
-
@remote_filename ||= File.join(remote_dir, File.basename(filename))
|
97
|
-
end
|
98
|
-
|
99
|
-
# The compression method to use, defaults to :gzip.
|
100
|
-
def compression
|
101
|
-
configuration[:copy_compression] || :gzip
|
102
|
-
end
|
103
|
-
|
104
|
-
# Returns the file extension used for the compression method in
|
105
|
-
# question.
|
106
|
-
def compression_extension
|
107
|
-
case compression
|
108
|
-
when :gzip, :gz then "tar.gz"
|
109
|
-
when :bzip2, :bz2 then "tar.bz2"
|
110
|
-
when :zip then "zip"
|
111
|
-
else raise ArgumentError, "invalid compression type #{compression.inspect}"
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# Returns the command necessary to compress the given directory
|
116
|
-
# into the given file. The command is returned as an array, where
|
117
|
-
# the first element is the utility to be used to perform the compression.
|
118
|
-
def compress(directory, file)
|
119
|
-
case compression
|
120
|
-
when :gzip, :gz then ["tar", "czf", file, directory]
|
121
|
-
when :bzip2, :bz2 then ["tar", "cjf", file, directory]
|
122
|
-
when :zip then ["zip", "-qr", file, directory]
|
123
|
-
else raise ArgumentError, "invalid compression type #{compression.inspect}"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# Returns the command necessary to decompress the given file,
|
128
|
-
# relative to the current working directory. It must also
|
129
|
-
# preserve the directory structure in the file. The command is returned
|
130
|
-
# as an array, where the first element is the utility to be used to
|
131
|
-
# perform the decompression.
|
132
|
-
def decompress(file)
|
133
|
-
case compression
|
134
|
-
when :gzip, :gz then ["tar", "xzf", file]
|
135
|
-
when :bzip2, :bz2 then ["tar", "xjf", file]
|
136
|
-
when :zip then ["unzip", "-q", file]
|
137
|
-
else raise ArgumentError, "invalid compression type #{compression.inspect}"
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'capistrano/recipes/deploy/strategy/remote'
|
2
|
-
|
3
|
-
module Capistrano
|
4
|
-
module Deploy
|
5
|
-
module Strategy
|
6
|
-
|
7
|
-
# Implements the deployment strategy which does an SCM export on each
|
8
|
-
# target host.
|
9
|
-
class Export < Remote
|
10
|
-
protected
|
11
|
-
|
12
|
-
# Returns the SCM's export command for the revision to deploy.
|
13
|
-
def command
|
14
|
-
@command ||= source.export(revision, configuration[:release_path])
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'capistrano/recipes/deploy/strategy/base'
|
2
|
-
|
3
|
-
module Capistrano
|
4
|
-
module Deploy
|
5
|
-
module Strategy
|
6
|
-
|
7
|
-
# An abstract superclass, which forms the base for all deployment
|
8
|
-
# strategies which work by grabbing the code from the repository directly
|
9
|
-
# from remote host. This includes deploying by checkout (the default),
|
10
|
-
# and deploying by export.
|
11
|
-
class Remote < Base
|
12
|
-
# Executes the SCM command for this strategy and writes the REVISION
|
13
|
-
# mark file to each host.
|
14
|
-
def deploy!
|
15
|
-
scm_run "#{command} && #{mark}"
|
16
|
-
end
|
17
|
-
|
18
|
-
def check!
|
19
|
-
super.check do |d|
|
20
|
-
d.remote.command(source.command)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
protected
|
25
|
-
|
26
|
-
# Runs the given command, filtering output back through the
|
27
|
-
# #handle_data filter of the SCM implementation.
|
28
|
-
def scm_run(command)
|
29
|
-
run(command) do |ch,stream,text|
|
30
|
-
ch[:state] ||= {}
|
31
|
-
output = source.handle_data(ch[:state], stream, text)
|
32
|
-
ch.send_data(output) if output
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# An abstract method which must be overridden in subclasses, to
|
37
|
-
# return the actual SCM command(s) which must be executed on each
|
38
|
-
# target host in order to perform the deployment.
|
39
|
-
def command
|
40
|
-
raise NotImplementedError, "`command' is not implemented by #{self.class.name}"
|
41
|
-
end
|
42
|
-
|
43
|
-
# Returns the command which will write the identifier of the
|
44
|
-
# revision being deployed to the REVISION file on each host.
|
45
|
-
def mark
|
46
|
-
"(echo #{revision} > #{configuration[:release_path]}/REVISION)"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'capistrano/recipes/deploy/strategy/remote'
|
2
|
-
|
3
|
-
module Capistrano
|
4
|
-
module Deploy
|
5
|
-
module Strategy
|
6
|
-
|
7
|
-
# Implements the deployment strategy that keeps a cached checkout of
|
8
|
-
# the source code on each remote server. Each deploy simply updates the
|
9
|
-
# cached checkout, and then does a copy from the cached copy to the
|
10
|
-
# final deployment location.
|
11
|
-
class RemoteCache < Remote
|
12
|
-
# Executes the SCM command for this strategy and writes the REVISION
|
13
|
-
# mark file to each host.
|
14
|
-
def deploy!
|
15
|
-
update_repository_cache
|
16
|
-
copy_repository_cache
|
17
|
-
end
|
18
|
-
|
19
|
-
def check!
|
20
|
-
super.check do |d|
|
21
|
-
d.remote.writable(shared_path)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def repository_cache
|
28
|
-
File.join(shared_path, configuration[:repository_cache] || "cached-copy")
|
29
|
-
end
|
30
|
-
|
31
|
-
def update_repository_cache
|
32
|
-
logger.trace "updating the cached checkout on all servers"
|
33
|
-
command = "if [ -d #{repository_cache} ]; then " +
|
34
|
-
"#{source.sync(revision, repository_cache)}; " +
|
35
|
-
"else #{source.checkout(revision, repository_cache)}; fi"
|
36
|
-
scm_run(command)
|
37
|
-
end
|
38
|
-
|
39
|
-
def copy_repository_cache
|
40
|
-
logger.trace "copying the cached version to #{configuration[:release_path]}"
|
41
|
-
run "cp -RPp #{repository_cache} #{configuration[:release_path]} && #{mark}"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module Capistrano
|
2
|
-
module Deploy
|
3
|
-
module Strategy
|
4
|
-
def self.new(strategy, config={})
|
5
|
-
strategy_file = "capistrano/recipes/deploy/strategy/#{strategy}"
|
6
|
-
require(strategy_file)
|
7
|
-
|
8
|
-
strategy_const = strategy.to_s.capitalize.gsub(/_(.)/) { $1.upcase }
|
9
|
-
if const_defined?(strategy_const)
|
10
|
-
const_get(strategy_const).new(config)
|
11
|
-
else
|
12
|
-
raise Capistrano::Error, "could not find `#{name}::#{strategy_const}' in `#{strategy_file}'"
|
13
|
-
end
|
14
|
-
rescue LoadError
|
15
|
-
raise Capistrano::Error, "could not find any strategy named `#{strategy}'"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
|
2
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
3
|
-
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
4
|
-
|
5
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
6
|
-
|
7
|
-
<head>
|
8
|
-
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
9
|
-
<title>System down for maintenance</title>
|
10
|
-
|
11
|
-
<style type="text/css">
|
12
|
-
div.outer {
|
13
|
-
position: absolute;
|
14
|
-
left: 50%;
|
15
|
-
top: 50%;
|
16
|
-
width: 500px;
|
17
|
-
height: 300px;
|
18
|
-
margin-left: -260px;
|
19
|
-
margin-top: -150px;
|
20
|
-
}
|
21
|
-
|
22
|
-
.DialogBody {
|
23
|
-
margin: 0;
|
24
|
-
padding: 10px;
|
25
|
-
text-align: left;
|
26
|
-
border: 1px solid #ccc;
|
27
|
-
border-right: 1px solid #999;
|
28
|
-
border-bottom: 1px solid #999;
|
29
|
-
background-color: #fff;
|
30
|
-
}
|
31
|
-
|
32
|
-
body { background-color: #fff; }
|
33
|
-
</style>
|
34
|
-
</head>
|
35
|
-
|
36
|
-
<body>
|
37
|
-
|
38
|
-
<div class="outer">
|
39
|
-
<div class="DialogBody" style="text-align: center;">
|
40
|
-
<div style="text-align: center; width: 200px; margin: 0 auto;">
|
41
|
-
<p style="color: red; font-size: 16px; line-height: 20px;">
|
42
|
-
The system is down for <%= reason ? reason : "maintenance" %>
|
43
|
-
as of <%= Time.now.strftime("%H:%M %Z") %>.
|
44
|
-
</p>
|
45
|
-
<p style="color: #666;">
|
46
|
-
It'll be back <%= deadline ? deadline : "shortly" %>.
|
47
|
-
</p>
|
48
|
-
</div>
|
49
|
-
</div>
|
50
|
-
</div>
|
51
|
-
|
52
|
-
</body>
|
53
|
-
</html>
|