dokuen 0.0.4 → 0.0.5
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 -0
- data/bin/dokuen +1 -1
- data/bin/dokuen_restart_nginx +1 -4
- data/data/templates/bin_command.erb +3 -0
- data/data/templates/deploy_command.erb +3 -0
- data/data/templates/gitolite_command.erb +4 -0
- data/data/templates/instructions.erb +24 -0
- data/data/templates/mac_launchdaemon.erb +19 -0
- data/data/templates/nginx.erb +22 -0
- data/data/templates/pre_receive_hook.erb +16 -0
- data/data/templates/ubuntu_upstart.erb +5 -0
- data/lib/dokuen/application.rb +279 -0
- data/lib/dokuen/cli.rb +134 -197
- data/lib/dokuen/config.rb +23 -0
- data/lib/dokuen/platform.rb +16 -0
- data/lib/dokuen/version.rb +1 -1
- data/lib/dokuen/wrapper.rb +127 -0
- data/lib/dokuen.rb +14 -41
- metadata +14 -3
- data/lib/dokuen/deploy.rb +0 -173
data/README.md
CHANGED
@@ -44,6 +44,8 @@ Create a `git` user and install gitolite according to [package directions](http:
|
|
44
44
|
Run this:
|
45
45
|
|
46
46
|
```
|
47
|
+
$ sudo mkdir -p /usr/local/var/dokuen
|
48
|
+
$ cd /usr/local/var/dokuen
|
47
49
|
$ sudo dokuen setup
|
48
50
|
```
|
49
51
|
|
@@ -108,3 +110,4 @@ $ ssh git@<your_host> dokuen restart_app <name>
|
|
108
110
|
|
109
111
|
Unfortunately the stock Heroku buildpacks install a vendored node.js compiled for the Heroku platform, which happens to be linux. This doesn't work for Mac, which means you have to use a slightly patched version. This one works with a homebrew-installed node.js: https://github.com/peterkeen/heroku-buildpack-ruby
|
110
112
|
|
113
|
+
|
data/bin/dokuen
CHANGED
data/bin/dokuen_restart_nginx
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
==== IMPORTANT INSTRUCTIONS ====
|
2
|
+
|
3
|
+
In your .gitolite.rc file, in the COMMANDS section, add the following:
|
4
|
+
|
5
|
+
'dokuen' => 1
|
6
|
+
|
7
|
+
In your gitolite.conf file, add the following:
|
8
|
+
|
9
|
+
repo apps/[a-zA-Z0-9].*
|
10
|
+
C = @all
|
11
|
+
RW+ = CREATOR
|
12
|
+
config hooks.pre = "<%= File.expand_path('./bin/dokuen-deploy') %>"
|
13
|
+
|
14
|
+
In your nginx.conf, add the following to your http section:
|
15
|
+
|
16
|
+
include "<%= File.expand_path('nginx') %>/*.conf";
|
17
|
+
|
18
|
+
Run "sudo visudo" and add the following lines:
|
19
|
+
|
20
|
+
Runas_Alias APPUSERS = <%= options[:appuser] %>
|
21
|
+
|
22
|
+
git ALL=(APPUSERS) NOPASSWD: <%= File.expand_path('./bin/dokuen') %>
|
23
|
+
<%= options[:appuser] %> ALL=NOPASSWD: <%= @current_bin_path %>/dokuen_restart_nginx
|
24
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>Label</key>
|
6
|
+
<string>info.bugpslat.dokuen</string>
|
7
|
+
<key>ProgramArguments</key>
|
8
|
+
<array>
|
9
|
+
<string><%= File.expand_path("./bin/dokuen") %></string>
|
10
|
+
<string>boot</string>
|
11
|
+
</array>
|
12
|
+
<key>RunAtLoad</key>
|
13
|
+
<true/>
|
14
|
+
<key>WorkingDirectory</key>
|
15
|
+
<string><%= File.expand_path(".") %></string>
|
16
|
+
<key>UserName</key>
|
17
|
+
<string<%= options[:appuser] %></string>
|
18
|
+
</dict>
|
19
|
+
</plist>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<% if ports.length > 0 %>
|
2
|
+
upstream <%= name %> {
|
3
|
+
<% ports.each do |port| %>
|
4
|
+
server localhost:<%= port %>;
|
5
|
+
<% end %>
|
6
|
+
}
|
7
|
+
|
8
|
+
server {
|
9
|
+
listen 80;
|
10
|
+
listen 443 default ssl;
|
11
|
+
|
12
|
+
server_name <%= name %>.<%= config.base_domain_name %>;
|
13
|
+
|
14
|
+
if ($ssl_protocol = "") {
|
15
|
+
rewrite ^ https://$server_name$request_uri? permanent;
|
16
|
+
}
|
17
|
+
|
18
|
+
location / {
|
19
|
+
proxy_pass http://<%= name %>;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
hook = `git config hooks.pre`.chomp
|
3
|
+
|
4
|
+
rev = nil
|
5
|
+
|
6
|
+
STDIN.each do |line|
|
7
|
+
parts = line.split(/\s/)
|
8
|
+
next if parts[2] != "refs/heads/master"
|
9
|
+
rev = parts[1]
|
10
|
+
end
|
11
|
+
|
12
|
+
if hook != ""
|
13
|
+
name = File.basename(ENV['GL_REPO']).gsub(".git", '')
|
14
|
+
cmd = "env REV=#{rev} APP=#{name} #{hook}"
|
15
|
+
system(cmd) or raise "Error running pre-hook: #{cmd} returned #{$?}"
|
16
|
+
end
|
@@ -0,0 +1,279 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
class Dokuen::Application
|
6
|
+
|
7
|
+
attr_reader :name, :config
|
8
|
+
|
9
|
+
def initialize(name, config)
|
10
|
+
@name = name
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_env(var)
|
15
|
+
with_app_dir do
|
16
|
+
env_path = File.join("env", var)
|
17
|
+
if File.exists?(env_path)
|
18
|
+
return File.read(env_path)
|
19
|
+
else
|
20
|
+
return nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_env(var, val)
|
26
|
+
with_app_dir do
|
27
|
+
env_path = File.join("env", var)
|
28
|
+
File.open(env_path, "w+") do |f|
|
29
|
+
f.write(val)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete_env(var)
|
35
|
+
with_app_dir do
|
36
|
+
File.delete(File.join("env", var)) rescue nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def env
|
41
|
+
vars = read_env_dir("#{config.dokuen_dir}/env")
|
42
|
+
with_app_dir do
|
43
|
+
vars.merge!(read_env_dir('env'))
|
44
|
+
with_current_release do
|
45
|
+
File.open(".env") do |f|
|
46
|
+
f.lines.each do |line|
|
47
|
+
key, val = line.split('=', 2)
|
48
|
+
vars[key] = val.chomp
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
vars
|
54
|
+
end
|
55
|
+
|
56
|
+
def create
|
57
|
+
Dir.chdir(File.join(config.dokuen_dir, 'apps')) do
|
58
|
+
if File.exists?(name)
|
59
|
+
raise "Application #{name} exists!"
|
60
|
+
end
|
61
|
+
|
62
|
+
FileUtils.mkdir_p(name)
|
63
|
+
with_app_dir do
|
64
|
+
dirs = [
|
65
|
+
'releases',
|
66
|
+
'env',
|
67
|
+
'logs',
|
68
|
+
'build'
|
69
|
+
]
|
70
|
+
FileUtils.mkdir_p(dirs)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def deploy(revision)
|
76
|
+
git_dir = Dir.getwd
|
77
|
+
|
78
|
+
with_app_dir do
|
79
|
+
now = Time.now().utc().strftime("%Y%m%dT%H%M%S")
|
80
|
+
release_dir = "releases/#{now}"
|
81
|
+
clone_dir = clone(git_dir, revision)
|
82
|
+
|
83
|
+
buildpack = get_env('BUILDPACK_URL')
|
84
|
+
if buildpack
|
85
|
+
buildpack = "-b #{buildpack}"
|
86
|
+
else
|
87
|
+
buildpack = ''
|
88
|
+
end
|
89
|
+
|
90
|
+
sys("mason build #{clone_dir} #{buildpack} -o #{release_dir} -c build")
|
91
|
+
Dir.mkdir("#{release_dir}/.dokuen")
|
92
|
+
|
93
|
+
hook = get_env('DOKUEN_AFTER_BUILD')
|
94
|
+
if hook
|
95
|
+
sys("foreman run #{hook}")
|
96
|
+
end
|
97
|
+
|
98
|
+
if File.symlink?("previous")
|
99
|
+
File.unlink("previous")
|
100
|
+
File.symlink(File.readlink("current"), "previous")
|
101
|
+
end
|
102
|
+
|
103
|
+
if File.symlink?("current")
|
104
|
+
File.unlink("current")
|
105
|
+
end
|
106
|
+
|
107
|
+
File.symlink(File.expand_path(release_dir), "current")
|
108
|
+
end
|
109
|
+
|
110
|
+
scale
|
111
|
+
if File.symlink?("previous")
|
112
|
+
shutdown(File.readlink("previous"))
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def scale
|
117
|
+
puts "Scaling..."
|
118
|
+
with_current_release do
|
119
|
+
processes = running_processes
|
120
|
+
running_count_by_name = {}
|
121
|
+
|
122
|
+
processes.each do |proc, pidfile|
|
123
|
+
proc_name = proc.split('.')[0]
|
124
|
+
running_count_by_name[proc_name] ||= 0
|
125
|
+
running_count_by_name[proc_name] += 1
|
126
|
+
end
|
127
|
+
|
128
|
+
desired_count_by_name = {}
|
129
|
+
scale_spec = get_env('DOKUEN_SCALE')
|
130
|
+
if scale_spec
|
131
|
+
scale_spec.split(',').each do |spec|
|
132
|
+
proc_name, count = spec.split('=')
|
133
|
+
desired_count_by_name[proc_name] = count.to_i
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
to_start = []
|
138
|
+
to_stop = []
|
139
|
+
|
140
|
+
desired_count_by_name.each do |proc_name, count|
|
141
|
+
running = running_count_by_name[proc_name] || 0
|
142
|
+
if running < count
|
143
|
+
(count - running).times do |i|
|
144
|
+
index = running + i + 1
|
145
|
+
to_start << [proc_name, index]
|
146
|
+
end
|
147
|
+
elsif running > count
|
148
|
+
(running - count).times do |i|
|
149
|
+
index = count + i + 1
|
150
|
+
to_stop << [proc_name, index]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
running_count_by_name.each do |proc_name, count|
|
156
|
+
if not desired_count_by_name.has_key?(proc_name)
|
157
|
+
count.times do |i|
|
158
|
+
to_stop << [proc_name, i]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
to_start.each do |proc_name, index|
|
164
|
+
port = reserve_port
|
165
|
+
fork do
|
166
|
+
Dokuen::Wrapper.new(self, proc_name, index, File.join(config.dokuen_dir, 'ports', port.to_s)).run!
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
to_stop.each do |proc_name, index|
|
171
|
+
pid_file = processes["#{proc_name}.#{index}"]
|
172
|
+
pid = YAML.load(File.read(pid_file))['pid']
|
173
|
+
Process.kill("TERM", pid)
|
174
|
+
end
|
175
|
+
install_nginx_config
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def shutdown(release)
|
180
|
+
with_release_dir(release) do
|
181
|
+
running_processes.each do |proc, pidfile|
|
182
|
+
pid = File.read(pidfile).to_i rescue nil
|
183
|
+
if pid
|
184
|
+
Process.kill("TERM", pid)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def install_nginx_config
|
191
|
+
puts "Installing nginx config"
|
192
|
+
sleep 2
|
193
|
+
@ssl_on = get_env('USE_SSL') ? 'on' : 'off'
|
194
|
+
@listen_port = get_env('USE_SSL') ? 443 : 80
|
195
|
+
conf = Dokuen.template('nginx', binding)
|
196
|
+
File.open(File.join(config.dokuen_dir, "nginx", "#{name}.#{config.base_domain_name}.conf"), "w+") do |f|
|
197
|
+
f.write(conf)
|
198
|
+
end
|
199
|
+
|
200
|
+
sys("sudo #{config.bin_path}/dokuen_restart_nginx")
|
201
|
+
end
|
202
|
+
|
203
|
+
private
|
204
|
+
|
205
|
+
def clone(git_dir, revision)
|
206
|
+
dir = Dir.mktmpdir
|
207
|
+
Dir.chdir(dir) do
|
208
|
+
sys("git clone #{git_dir} .")
|
209
|
+
sys("git checkout -q #{revision}")
|
210
|
+
end
|
211
|
+
dir
|
212
|
+
end
|
213
|
+
|
214
|
+
def sys(command)
|
215
|
+
system(command) or raise "Error running command: #{command}"
|
216
|
+
end
|
217
|
+
|
218
|
+
def with_app_dir
|
219
|
+
Dir.chdir(File.join(config.dokuen_dir, 'apps', name)) do
|
220
|
+
yield
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def with_release_dir(release)
|
225
|
+
Dir.chdir(release) do
|
226
|
+
yield
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def with_current_release
|
231
|
+
with_app_dir do
|
232
|
+
if File.symlink?("current")
|
233
|
+
with_release_dir(File.readlink("current")) do
|
234
|
+
yield
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def running_processes
|
241
|
+
procs = {}
|
242
|
+
Dir.glob(".dokuen/*.pid").map do |pidfile|
|
243
|
+
proc_name = File.basename(pidfile).gsub('.pid', '')
|
244
|
+
proc_name = proc_name.gsub("dokuen.#{name}.", '')
|
245
|
+
procs[proc_name] = pidfile
|
246
|
+
end
|
247
|
+
procs
|
248
|
+
end
|
249
|
+
|
250
|
+
def read_env_dir(dir)
|
251
|
+
vars = {}
|
252
|
+
Dir.glob("#{dir}/*").each do |key|
|
253
|
+
vars[File.basename(key)] = File.read(key).chomp
|
254
|
+
end
|
255
|
+
vars
|
256
|
+
end
|
257
|
+
|
258
|
+
def reserve_port
|
259
|
+
ports_dir = config.dokuen_dir + "/ports"
|
260
|
+
port_range = config.max_port - config.min_port
|
261
|
+
1000.times do
|
262
|
+
port = rand(port_range) + config.min_port
|
263
|
+
path = File.join(ports_dir, port.to_s)
|
264
|
+
if not File.exists?(path)
|
265
|
+
FileUtils.touch(path)
|
266
|
+
return port
|
267
|
+
end
|
268
|
+
end
|
269
|
+
raise "Could not find free port!"
|
270
|
+
end
|
271
|
+
|
272
|
+
def ports
|
273
|
+
_ports = []
|
274
|
+
running_processes.each do |proc_name, pidfile|
|
275
|
+
_ports << YAML.load(File.read(pidfile))['port']
|
276
|
+
end
|
277
|
+
_ports
|
278
|
+
end
|
279
|
+
end
|
data/lib/dokuen/cli.rb
CHANGED
@@ -1,226 +1,163 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "thor"
|
2
|
+
require "thor/shell/basic"
|
3
|
+
require "yaml"
|
4
4
|
|
5
|
-
|
6
|
-
class Cli < Thor
|
7
|
-
include Thor::Actions
|
8
|
-
|
9
|
-
desc "setup", "Set up relevant things. Needs to be run as sudo."
|
10
|
-
def setup
|
11
|
-
raise "Must be run as root" unless Process.uid == 0
|
12
|
-
git_username = ask("What is your git username (usually git)?")
|
13
|
-
gitolite_src = ask("What is the path to your gitolite clone?")
|
14
|
-
say("Installing gitolite command")
|
15
|
-
create_file "#{gitolite_src}/src/commands/dokuen", <<HERE
|
16
|
-
#!/bin/sh
|
17
|
-
/usr/local/bin/dokuen $@
|
18
|
-
HERE
|
19
|
-
File.chmod(0755, "#{gitolite_src}/src/commands/dokuen")
|
20
|
-
say("Installing gitolite hook")
|
21
|
-
hook_path = "/Users/#{git_username}/.gitolite/hooks/common/pre-receive"
|
22
|
-
create_file(hook_path, <<'HERE'
|
23
|
-
#!/usr/bin/env ruby
|
24
|
-
hook = `git config hooks.pre`.chomp
|
25
|
-
|
26
|
-
rev = nil
|
27
|
-
|
28
|
-
STDIN.each do |line|
|
29
|
-
parts = line.split(/\s/)
|
30
|
-
next if parts[2] != "refs/heads/master"
|
31
|
-
rev = parts[1]
|
32
|
-
end
|
33
|
-
|
34
|
-
if hook != ""
|
35
|
-
name = File.basename(ENV['GL_REPO'])
|
36
|
-
cmd = "#{hook} #{name} #{rev}"
|
37
|
-
system(cmd) or raise "Error running pre-hook: #{cmd} returned #{$?}"
|
38
|
-
end
|
39
|
-
HERE
|
40
|
-
)
|
41
|
-
File.chmod(0755, hook_path)
|
42
|
-
say("Creating directories")
|
43
|
-
dirs = [
|
44
|
-
'/usr/local/var/dokuen/env',
|
45
|
-
'/usr/local/var/dokuen/env/_common',
|
46
|
-
'/usr/local/var/dokuen/log',
|
47
|
-
'/usr/local/var/dokuen/nginx',
|
48
|
-
'/usr/local/var/dokuen/build',
|
49
|
-
'/usr/local/var/dokuen/release',
|
50
|
-
]
|
51
|
-
FileUtils.mkdir_p(dirs, :mode => 0775)
|
52
|
-
FileUtils.chown(git_username, 'staff', dirs)
|
53
|
-
|
54
|
-
if yes?("Do you want to set up DNS?")
|
55
|
-
basename = ask("What is your DNS base domain? For example, if have a wildcard CNAME for *.example.com, this would be example.com.")
|
56
|
-
create_file("/usr/local/var/dokuen/env/_common/BASE_DOMAIN", basename)
|
57
|
-
end
|
58
|
-
git_hostname = `hostname`.chomp
|
59
|
-
if no?("Is #{git_hostname} the correct hostname for git remotes?")
|
60
|
-
git_hostname = ask("What hostname should we use instead?")
|
61
|
-
end
|
62
|
-
create_file("/usr/local/var/dokuen/env/_common/DOKUEN_GIT_SERVER", git_hostname)
|
63
|
-
create_file("/usr/local/var/dokuen/env/_common/DOKUEN_GIT_USER", git_username)
|
64
|
-
|
65
|
-
say(<<HERE
|
66
|
-
|
67
|
-
==== IMPORTANT INSTRUCTIONS ====
|
68
|
-
|
69
|
-
In your .gitolite.rc file, in the COMMANDS section, add the following:
|
70
|
-
|
71
|
-
'dokuen' => 1
|
5
|
+
class Dokuen::CLI < Thor
|
72
6
|
|
73
|
-
|
7
|
+
include Thor::Actions
|
74
8
|
|
75
|
-
|
76
|
-
|
77
|
-
RW+ = CREATOR
|
78
|
-
config hooks.pre = "/usr/local/bin/dokuen deploy"
|
9
|
+
def initialize(*args)
|
10
|
+
super(*args)
|
79
11
|
|
80
|
-
|
12
|
+
if not options[:config].nil?
|
13
|
+
@config = Dokuen::Config.new(options[:config])
|
14
|
+
end
|
15
|
+
end
|
81
16
|
|
82
|
-
|
17
|
+
class_option :application, :type => :string, :desc => "Application name"
|
18
|
+
class_option :config, :type => :string, :desc => "Configuration file"
|
19
|
+
class_option :debug, :type => :boolean, :desc => "Show backtraces"
|
20
|
+
|
21
|
+
desc "setup DIR", "set up dokuen in the given directory"
|
22
|
+
method_option :gituser, :desc => "Username of git user", :default => 'git'
|
23
|
+
method_option :gitgroup, :desc => "Group of git user", :default => 'staff'
|
24
|
+
method_option :appuser, :desc => "Username of app user", :default => 'dokuen'
|
25
|
+
method_option :gitolite, :desc => "Path to gitolite directory", :default => 'GITUSER_HOME/gitolite'
|
26
|
+
method_option :platform, :desc => "Which platform to install. Can be 'mac', 'ubuntu', or 'centos'", :default => 'mac'
|
27
|
+
def setup(dir)
|
28
|
+
|
29
|
+
@current_script = File.expand_path($0)
|
30
|
+
@current_bin_path = File.dirname(@current_script)
|
31
|
+
|
32
|
+
Dir.chdir(dir) do
|
33
|
+
setup_dirs
|
34
|
+
setup_bin
|
35
|
+
setup_gitolite
|
36
|
+
write_config
|
37
|
+
install_boot_script
|
38
|
+
puts Dokuen.template('instructions', binding)
|
39
|
+
end
|
40
|
+
end
|
83
41
|
|
84
|
-
|
42
|
+
desc "create", "create application"
|
43
|
+
def create
|
44
|
+
Dokuen::Application.new(options[:application], @config).create
|
45
|
+
puts "git remote add dokuen #{@config.git_user}@#{@config.git_server}:apps/#{options[:application]}.git"
|
46
|
+
end
|
85
47
|
|
86
|
-
|
48
|
+
desc "deploy", "deploy application", :hide => true
|
49
|
+
method_option :rev, :desc => "Revision to deploy"
|
50
|
+
def deploy
|
51
|
+
ENV['GIT_DIR'] = nil
|
52
|
+
ENV['PATH'] = "#{@config.bin_path}:#{ENV['PATH']}"
|
53
|
+
ENV.each do |k,v|
|
54
|
+
puts "#{k}=#{v}"
|
55
|
+
end
|
56
|
+
Dokuen::Application.new(options[:application], @config).deploy(options[:rev])
|
57
|
+
end
|
87
58
|
|
88
|
-
|
89
|
-
|
59
|
+
desc "scale SCALE_SPEC", "scale to the given spec"
|
60
|
+
def scale(spec)
|
61
|
+
app = Dokuen::Application.new(options[:application], @config)
|
62
|
+
app.set_env('DOKUEN_SCALE', spec)
|
63
|
+
app.scale
|
64
|
+
end
|
90
65
|
|
66
|
+
desc "config", "show the config for the given app"
|
67
|
+
def config
|
68
|
+
app = Dokuen::Application.new(options[:application], @config)
|
69
|
+
app.env.each do |key, val|
|
70
|
+
puts "#{key}=#{val}"
|
91
71
|
end
|
72
|
+
end
|
92
73
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
FileUtils.mkdir_p(Dokuen.dir("build", app))
|
100
|
-
puts "Created new application named #{app}"
|
101
|
-
puts "Git remote: #{Dokuen.base_clone_url}:apps/#{app}.git"
|
74
|
+
desc "config_set VARS", "set some config variables"
|
75
|
+
def config_set(*vars)
|
76
|
+
app = Dokuen::Application.new(options[:application], @config)
|
77
|
+
vars.each do |var|
|
78
|
+
key, val = var.chomp.split('=', 2)
|
79
|
+
app.set_env(key, val)
|
102
80
|
end
|
81
|
+
end
|
103
82
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
deploy.install_launch_daemon
|
110
|
-
deploy.install_nginx_conf
|
111
|
-
puts "App restarted"
|
83
|
+
desc "config_delete VARS", "delete some config variables"
|
84
|
+
def config_delete(*vars)
|
85
|
+
app = Dokuen::Application.new(options[:application], @config)
|
86
|
+
vars.each do |var|
|
87
|
+
app.delete_env(var)
|
112
88
|
end
|
89
|
+
end
|
113
90
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
base_port = ENV['PORT'].to_i - 200
|
121
|
-
scale = ENV['DOKUEN_SCALE'].nil? ? "" : "-c #{ENV['DOKUEN_SCALE']}"
|
122
|
-
Dokuen.sys("foreman start #{scale} -p #{base_port}")
|
123
|
-
end
|
91
|
+
desc "boot", "Scale all of the current applications"
|
92
|
+
def boot
|
93
|
+
Dir.glob("#{@config.dokuen_dir}/apps/*") do |appdir|
|
94
|
+
next if File.basename(appdir)[0] == '.'
|
95
|
+
app = Dokuen::Application.new(File.basename(appdir), @config)
|
96
|
+
app.scale
|
124
97
|
end
|
98
|
+
end
|
125
99
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
100
|
+
private
|
101
|
+
|
102
|
+
def setup_dirs
|
103
|
+
dirs = [
|
104
|
+
'apps',
|
105
|
+
'env',
|
106
|
+
'ports',
|
107
|
+
'nginx',
|
108
|
+
'bin'
|
109
|
+
]
|
135
110
|
|
136
|
-
|
137
|
-
|
138
|
-
check_app(app)
|
139
|
-
read_env(app)
|
140
|
-
Dokuen::Deploy.new(app, rev).run
|
141
|
-
puts "App #{app} deployed"
|
111
|
+
dirs.each do |dir|
|
112
|
+
empty_directory(File.join(Dir.getwd, dir))
|
142
113
|
end
|
143
114
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
check_app(app)
|
148
|
-
read_env(app)
|
115
|
+
FileUtils.chown(options[:gituser], options[:gitgroup], dirs)
|
116
|
+
FileUtils.chmod(0777, ['apps', 'ports', 'nginx'])
|
117
|
+
end
|
149
118
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
119
|
+
def setup_bin
|
120
|
+
@script_path = File.expand_path("bin/dokuen")
|
121
|
+
@deploy_script_path = File.expand_path("bin/dokuen-deploy")
|
122
|
+
write_template(@script_path, "bin_command", 0755)
|
123
|
+
write_template(@deploy_script_path, "deploy_command", 0755)
|
124
|
+
end
|
155
125
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
check_app(app)
|
160
|
-
case subcommand
|
161
|
-
when "set"
|
162
|
-
set_vars(app)
|
163
|
-
restart_app(app)
|
164
|
-
when "delete"
|
165
|
-
delete_vars(app)
|
166
|
-
restart_app(app)
|
167
|
-
else
|
168
|
-
show_vars(app)
|
169
|
-
end
|
170
|
-
end
|
126
|
+
def setup_gitolite
|
127
|
+
githome = File.expand_path("~#{options[:gituser]}")
|
128
|
+
gitolite = options[:gitolite].gsub('GITUSER_HOME', githome)
|
171
129
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
Dokuen.sys("/usr/local/bin/mason buildpacks:install #{url}")
|
176
|
-
end
|
130
|
+
write_template("#{gitolite}/src/commands/dokuen", 'gitolite_command', 0755)
|
131
|
+
write_template("#{githome}/.gitolite/hooks/common/pre-receive", 'pre_receive_hook', 0755)
|
132
|
+
end
|
177
133
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
134
|
+
def write_config
|
135
|
+
config = {
|
136
|
+
'base_domain_name' => 'dokuen',
|
137
|
+
'git_server' => `hostname`.chomp,
|
138
|
+
'git_user' => options[:gituser],
|
139
|
+
'app_user' => options[:appuser],
|
140
|
+
'min_port' => 5000,
|
141
|
+
'max_port' => 6000,
|
142
|
+
'bin_path' => @current_bin_path,
|
143
|
+
'dokuen_dir' => File.expand_path('.')
|
144
|
+
}
|
145
|
+
|
146
|
+
File.open("./dokuen.conf", 'w+') do |f|
|
147
|
+
YAML.dump(config, f)
|
182
148
|
end
|
149
|
+
|
150
|
+
end
|
183
151
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
152
|
+
def write_template(filename, template, mode=0644)
|
153
|
+
t = Dokuen.template(template, binding)
|
154
|
+
create_file(filename, t)
|
155
|
+
File.chmod(mode, filename)
|
156
|
+
end
|
188
157
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
vars = options[:vars]
|
193
|
-
vars.each do |var|
|
194
|
-
key, val = var.split(/\=/)
|
195
|
-
Dokuen.set_env(app, key, val)
|
196
|
-
end
|
197
|
-
puts "Vars set"
|
198
|
-
end
|
199
|
-
|
200
|
-
def delete_vars(app)
|
201
|
-
vars = options[:vars]
|
202
|
-
|
203
|
-
vars.each do |var|
|
204
|
-
Dokuen.rm_env(app, var)
|
205
|
-
end
|
206
|
-
puts "Vars removed"
|
207
|
-
end
|
208
|
-
|
209
|
-
def show_vars(app)
|
210
|
-
read_env(app)
|
211
|
-
ENV.each do |key, val|
|
212
|
-
puts "#{key}=#{val}"
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
def read_env(app)
|
217
|
-
Dokuen.read_env("_common")
|
218
|
-
Dokuen.read_env(app)
|
219
|
-
end
|
220
|
-
|
221
|
-
def check_app(app)
|
222
|
-
Dokuen.app_exists?(app) or raise "App '#{app}' does not exist!"
|
223
|
-
end
|
224
|
-
end
|
158
|
+
def install_boot_script
|
159
|
+
filename, template_name = Dokuen::Platform.boot_script(options[:platform])
|
160
|
+
write_template(filename, template_name)
|
225
161
|
end
|
162
|
+
|
226
163
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
class Dokuen::Config
|
4
|
+
def initialize(path)
|
5
|
+
@path = path
|
6
|
+
@config = {}
|
7
|
+
read_config
|
8
|
+
end
|
9
|
+
|
10
|
+
def read_config
|
11
|
+
@config = YAML.load(File.read(@path))
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(m, *args, &block)
|
15
|
+
str_meth = m.to_s
|
16
|
+
if @config.has_key? str_meth
|
17
|
+
@config[str_meth]
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Dokuen
|
2
|
+
module Platform
|
3
|
+
|
4
|
+
def self.boot_script(platform)
|
5
|
+
case platform
|
6
|
+
when 'mac'
|
7
|
+
return "/Library/LaunchDaemons/dokuen.plist", "mac_launchdaemon"
|
8
|
+
when 'ubuntu'
|
9
|
+
return "/etc/init/dokuen", "ubuntu_upstart"
|
10
|
+
else
|
11
|
+
raise "Unknow platform: #{platform}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
data/lib/dokuen/version.rb
CHANGED
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'foreman'
|
2
|
+
require 'foreman/procfile'
|
3
|
+
require 'foreman/process'
|
4
|
+
|
5
|
+
class Dokuen::Wrapper
|
6
|
+
|
7
|
+
attr_reader :release_dir, :app, :proc, :index, :portfile
|
8
|
+
|
9
|
+
def initialize(app, proc, index, portfile)
|
10
|
+
@release_dir = Dir.getwd
|
11
|
+
@app = app
|
12
|
+
@proc = proc
|
13
|
+
@index = index
|
14
|
+
@portfile = portfile
|
15
|
+
end
|
16
|
+
|
17
|
+
def run!
|
18
|
+
return if daemonize! == nil
|
19
|
+
load_env
|
20
|
+
loop do
|
21
|
+
run_loop
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def procname
|
26
|
+
"dokuen.#{app.name}.#{proc}.#{index}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def procdir
|
30
|
+
File.join(release_dir, '.dokuen')
|
31
|
+
end
|
32
|
+
|
33
|
+
def pidfile
|
34
|
+
File.join(procdir, "#{procname}.pid")
|
35
|
+
end
|
36
|
+
|
37
|
+
def outfile
|
38
|
+
File.join(procdir, "#{procname}.out")
|
39
|
+
end
|
40
|
+
|
41
|
+
def errfile
|
42
|
+
File.join(procdir, "#{procname}.err")
|
43
|
+
end
|
44
|
+
|
45
|
+
def port
|
46
|
+
File.basename(portfile).to_i
|
47
|
+
end
|
48
|
+
|
49
|
+
def daemonize!
|
50
|
+
pf = File.join(pidfile)
|
51
|
+
raise "Process already running!" if File.exists?(pf)
|
52
|
+
|
53
|
+
return unless do_fork.nil?
|
54
|
+
write_pidfile
|
55
|
+
set_procname
|
56
|
+
redirect
|
57
|
+
end
|
58
|
+
|
59
|
+
def redirect
|
60
|
+
$stdin.reopen("/dev/null")
|
61
|
+
$stdout.sync = $stderr.sync = true
|
62
|
+
$stdout.reopen(File.new(outfile, "a"))
|
63
|
+
$stderr.reopen(File.new(errfile, "a"))
|
64
|
+
end
|
65
|
+
|
66
|
+
def write_pidfile
|
67
|
+
File.open(pidfile, "w+") do |f|
|
68
|
+
f.write(YAML.dump({'pid' => Process.pid, 'port' => port}))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_procname
|
73
|
+
$0 = procname
|
74
|
+
end
|
75
|
+
|
76
|
+
def do_fork
|
77
|
+
raise 'first fork failed' if (pid = fork) == -1
|
78
|
+
exit unless pid.nil?
|
79
|
+
Process.setsid
|
80
|
+
raise 'second fork failed' if (pid = fork) == -1
|
81
|
+
exit unless pid.nil?
|
82
|
+
end
|
83
|
+
|
84
|
+
def load_env
|
85
|
+
app.env.each do |key, val|
|
86
|
+
ENV[key] = val
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def run_loop
|
91
|
+
reader, writer = (IO.method(:pipe).arity == 0 ? IO.pipe : IO.pipe("BINARY"))
|
92
|
+
procfile = Foreman::Procfile.new("Procfile")
|
93
|
+
entry = procfile[proc]
|
94
|
+
process = Foreman::Process.new(entry, index.to_i, port.to_i)
|
95
|
+
log_path = "../../logs/#{procname}"
|
96
|
+
log_file = File.open(log_path, 'a')
|
97
|
+
|
98
|
+
Signal.trap("USR2") do
|
99
|
+
process.kill("TERM")
|
100
|
+
end
|
101
|
+
|
102
|
+
Signal.trap("TERM") do
|
103
|
+
if not process.kill(9)
|
104
|
+
raise "Failed to kill process #{process.pid}"
|
105
|
+
end
|
106
|
+
File.delete(pidfile)
|
107
|
+
File.delete("../../../../ports/#{port}")
|
108
|
+
exit! 0
|
109
|
+
end
|
110
|
+
|
111
|
+
process.run(writer, release_dir, {})
|
112
|
+
thread = Thread.new do
|
113
|
+
loop do
|
114
|
+
data = reader.gets
|
115
|
+
next unless data
|
116
|
+
ps, message = data.split(",", 2)
|
117
|
+
log_file.puts("[#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}][#{ps}] #{message}")
|
118
|
+
log_file.flush
|
119
|
+
end
|
120
|
+
end
|
121
|
+
Process.wait(process.pid)
|
122
|
+
thread.exit
|
123
|
+
reader.close
|
124
|
+
writer.close
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
data/lib/dokuen.rb
CHANGED
@@ -1,46 +1,19 @@
|
|
1
|
-
require
|
2
|
-
require 'dokuen/deploy'
|
1
|
+
require "erb"
|
3
2
|
|
4
3
|
module Dokuen
|
5
|
-
def self.
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
File.join(parts)
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.sys(command)
|
16
|
-
system(command) or raise "Error running #{command}"
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.read_env(name)
|
20
|
-
env_dir = Dokuen.dir('env', name)
|
21
|
-
Dir.glob("#{env_dir}/*") do |var|
|
22
|
-
var_name = File.basename(var)
|
23
|
-
ENV[var_name] = File.open(var).read().chomp()
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.set_env(name, key, value)
|
28
|
-
env_dir = Dokuen.dir('env', name)
|
29
|
-
File.open(File.join(env_dir, key), "w+") do |f|
|
30
|
-
f.write value
|
4
|
+
def self.template(name, bind)
|
5
|
+
path = File.expand_path("../../data/templates/#{name}.erb", __FILE__)
|
6
|
+
if File.exists?(path)
|
7
|
+
t = ERB.new(File.read(path))
|
8
|
+
t.result(bind)
|
9
|
+
else
|
10
|
+
raise "Unknown template: #{name}"
|
31
11
|
end
|
32
12
|
end
|
33
|
-
|
34
|
-
def self.rm_env(name, key)
|
35
|
-
env_dir = Dokuen.dir('env', name)
|
36
|
-
File.delete(File.join(env_dir, key))
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.base_clone_url
|
40
|
-
"#{ENV['DOKUEN_GIT_USER']}@#{ENV['DOKUEN_GIT_SERVER']}"
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.app_exists?(name)
|
44
|
-
File.exists?(Dokuen.dir('env', name))
|
45
|
-
end
|
46
13
|
end
|
14
|
+
|
15
|
+
require "dokuen/cli"
|
16
|
+
require "dokuen/config"
|
17
|
+
require "dokuen/application"
|
18
|
+
require "dokuen/wrapper"
|
19
|
+
require "dokuen/platform"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dokuen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-29 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -91,11 +91,22 @@ files:
|
|
91
91
|
- bin/dokuen
|
92
92
|
- bin/dokuen_install_launchdaemon
|
93
93
|
- bin/dokuen_restart_nginx
|
94
|
+
- data/templates/bin_command.erb
|
95
|
+
- data/templates/deploy_command.erb
|
96
|
+
- data/templates/gitolite_command.erb
|
97
|
+
- data/templates/instructions.erb
|
98
|
+
- data/templates/mac_launchdaemon.erb
|
99
|
+
- data/templates/nginx.erb
|
100
|
+
- data/templates/pre_receive_hook.erb
|
101
|
+
- data/templates/ubuntu_upstart.erb
|
94
102
|
- dokuen.gemspec
|
95
103
|
- lib/dokuen.rb
|
104
|
+
- lib/dokuen/application.rb
|
96
105
|
- lib/dokuen/cli.rb
|
97
|
-
- lib/dokuen/
|
106
|
+
- lib/dokuen/config.rb
|
107
|
+
- lib/dokuen/platform.rb
|
98
108
|
- lib/dokuen/version.rb
|
109
|
+
- lib/dokuen/wrapper.rb
|
99
110
|
homepage: https://github.com/peterkeen/dokuen
|
100
111
|
licenses: []
|
101
112
|
post_install_message:
|
data/lib/dokuen/deploy.rb
DELETED
@@ -1,173 +0,0 @@
|
|
1
|
-
require 'tmpdir'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'time'
|
4
|
-
require 'erb'
|
5
|
-
|
6
|
-
module Dokuen
|
7
|
-
class Deploy
|
8
|
-
|
9
|
-
def initialize(app, rev, release_dir=nil)
|
10
|
-
@app = app || app_name_from_env
|
11
|
-
@rev = rev
|
12
|
-
ENV['GIT_DIR'] = nil
|
13
|
-
ENV['PATH'] = "/usr/local/bin:#{ENV['PATH']}"
|
14
|
-
if release_dir
|
15
|
-
@release_dir = release_dir
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def run
|
20
|
-
read_app_env
|
21
|
-
make_dirs
|
22
|
-
clone
|
23
|
-
build
|
24
|
-
install_launch_daemon
|
25
|
-
install_nginx_conf
|
26
|
-
end
|
27
|
-
|
28
|
-
def read_app_env
|
29
|
-
Dokuen.read_env('_common')
|
30
|
-
Dokuen.read_env(@app)
|
31
|
-
end
|
32
|
-
|
33
|
-
def make_dirs
|
34
|
-
FileUtils.mkdir_p([
|
35
|
-
env_dir,
|
36
|
-
release_dir,
|
37
|
-
cache_dir,
|
38
|
-
nginx_dir
|
39
|
-
])
|
40
|
-
end
|
41
|
-
|
42
|
-
def clone
|
43
|
-
Dokuen.sys("git clone #{git_dir} #{clone_dir}")
|
44
|
-
Dir.chdir(clone_dir)
|
45
|
-
Dokuen.sys("git checkout #{@rev}")
|
46
|
-
end
|
47
|
-
|
48
|
-
def build
|
49
|
-
Dokuen.sys("mason build #{clone_dir} #{buildpack} -o #{release_dir} -c #{cache_dir}")
|
50
|
-
Dokuen.sys("chmod -R a+r #{release_dir}")
|
51
|
-
Dokuen.sys("find #{release_dir} -type d -exec chmod a+x {} \\;")
|
52
|
-
Dokuen.set_env(@app, 'DOKUEN_RELEASE_DIR', release_dir)
|
53
|
-
|
54
|
-
hook = ENV['DOKUEN_AFTER_BUILD']
|
55
|
-
if not hook.nil?
|
56
|
-
Dir.chdir release_dir do
|
57
|
-
Dokuen.sys("foreman run #{hook}")
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def buildpack
|
63
|
-
if not ENV['BUILDPACK_URL'].nil?
|
64
|
-
"-b #{ENV['BUILDPACK_URL']}"
|
65
|
-
else
|
66
|
-
""
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def install_launch_daemon
|
71
|
-
t = ERB.new(launch_daemon_template)
|
72
|
-
plist_path = File.join(release_dir, "dokuen.#{@app}.plist")
|
73
|
-
File.open(plist_path, "w+") do |f|
|
74
|
-
f.write(t.result(binding))
|
75
|
-
end
|
76
|
-
Dokuen.sys("sudo /usr/local/bin/dokuen_install_launchdaemon #{plist_path}")
|
77
|
-
end
|
78
|
-
|
79
|
-
def install_nginx_conf
|
80
|
-
t = ERB.new(nginx_template)
|
81
|
-
File.open(File.join(nginx_dir, "#{@app}.#{base_domain}.conf"), "w+") do |f|
|
82
|
-
f.write(t.result(binding))
|
83
|
-
end
|
84
|
-
Dokuen.sys("sudo /usr/local/bin/dokuen_restart_nginx")
|
85
|
-
end
|
86
|
-
|
87
|
-
def base_domain
|
88
|
-
ENV['BASE_DOMAIN'] || 'dokuen'
|
89
|
-
end
|
90
|
-
|
91
|
-
def app_name_from_env
|
92
|
-
File.basename(ENV['GL_REPO']).gsub(/\.git$/, '')
|
93
|
-
end
|
94
|
-
|
95
|
-
def env_dir
|
96
|
-
Dokuen.dir("env", @app)
|
97
|
-
end
|
98
|
-
|
99
|
-
def clone_dir
|
100
|
-
@clone_dir ||= Dir.mktmpdir
|
101
|
-
end
|
102
|
-
|
103
|
-
def git_dir
|
104
|
-
@git_dir || Dir.getwd
|
105
|
-
end
|
106
|
-
|
107
|
-
def release_dir
|
108
|
-
@now = Time.now().utc().strftime("%Y%m%dT%H%M%S")
|
109
|
-
@release_dir ||= File.join(Dokuen.dir('release', @app), @now)
|
110
|
-
end
|
111
|
-
|
112
|
-
def cache_dir
|
113
|
-
Dokuen.dir('build', @app)
|
114
|
-
end
|
115
|
-
|
116
|
-
def nginx_dir
|
117
|
-
Dokuen.dir('nginx')
|
118
|
-
end
|
119
|
-
|
120
|
-
def server_port
|
121
|
-
ENV['USE_SSL'] ? "443" : "80"
|
122
|
-
end
|
123
|
-
|
124
|
-
def ssl_on
|
125
|
-
ENV['USE_SSL'] ? "on" : "off"
|
126
|
-
end
|
127
|
-
|
128
|
-
def launch_daemon_template
|
129
|
-
<<HERE
|
130
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
131
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
132
|
-
<plist version="1.0">
|
133
|
-
<dict>
|
134
|
-
<key>KeepAlive</key>
|
135
|
-
<true/>
|
136
|
-
<key>Label</key>
|
137
|
-
<string>dokuen.<%= @app %></string>
|
138
|
-
<key>ProgramArguments</key>
|
139
|
-
<array>
|
140
|
-
<string>/usr/local/bin/dokuen</string>
|
141
|
-
<string>start_app</string>
|
142
|
-
<string><%= @app %></string>
|
143
|
-
</array>
|
144
|
-
<key>RunAtLoad</key>
|
145
|
-
<true/>
|
146
|
-
<key>UserName</key>
|
147
|
-
<string>peter</string>
|
148
|
-
<key>WorkingDirectory</key>
|
149
|
-
<string>/usr/local/var/dokuen</string>
|
150
|
-
<key>StandardOutPath</key>
|
151
|
-
<string>/usr/local/var/dokuen/log/<%= @app %>.log</string>
|
152
|
-
<key>StandardErrorPath</key>
|
153
|
-
<string>/usr/local/var/dokuen/log/<%= @app %>.log</string>
|
154
|
-
</dict>
|
155
|
-
</plist>
|
156
|
-
HERE
|
157
|
-
end
|
158
|
-
|
159
|
-
def nginx_template
|
160
|
-
<<HERE
|
161
|
-
server {
|
162
|
-
server_name <%= @app %>.<%= base_domain %>;
|
163
|
-
listen <%= server_port %>;
|
164
|
-
ssl <%= ssl_on %>;
|
165
|
-
location / {
|
166
|
-
proxy_pass http://localhost:<%= ENV['PORT'] %>/;
|
167
|
-
}
|
168
|
-
}
|
169
|
-
HERE
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|