circus-deployment 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +23 -0
- data/README.md +0 -0
- data/bin/circus +24 -0
- data/lib/bundler/circus_bundler.rb +24 -0
- data/lib/bundler/circus_util.rb +43 -0
- data/lib/bundler/patches.rb +18 -0
- data/lib/circus/act.rb +74 -0
- data/lib/circus/actstore_client.rb +30 -0
- data/lib/circus/agents/agent.rb +59 -0
- data/lib/circus/agents/client.rb +77 -0
- data/lib/circus/agents/connection.rb +76 -0
- data/lib/circus/agents/conversation.rb +17 -0
- data/lib/circus/agents/dbus_connection.rb +85 -0
- data/lib/circus/agents/dbus_logger.rb +34 -0
- data/lib/circus/agents/encoding.rb +32 -0
- data/lib/circus/agents/logger.rb +52 -0
- data/lib/circus/agents/params.rb +47 -0
- data/lib/circus/agents/ssh_connection.rb +120 -0
- data/lib/circus/application.rb +99 -0
- data/lib/circus/booth_client.rb +25 -0
- data/lib/circus/booth_tool.rb +98 -0
- data/lib/circus/cli.rb +147 -0
- data/lib/circus/clown_client.rb +27 -0
- data/lib/circus/connection_builder.rb +32 -0
- data/lib/circus/external_util.rb +14 -0
- data/lib/circus/local_config.rb +65 -0
- data/lib/circus/profiles/base.rb +115 -0
- data/lib/circus/profiles/django.rb +90 -0
- data/lib/circus/profiles/jekyll.rb +90 -0
- data/lib/circus/profiles/make_base.rb +17 -0
- data/lib/circus/profiles/pure_py.rb +46 -0
- data/lib/circus/profiles/pure_rb.rb +48 -0
- data/lib/circus/profiles/python_base.rb +39 -0
- data/lib/circus/profiles/rack.rb +59 -0
- data/lib/circus/profiles/ruby_base.rb +52 -0
- data/lib/circus/profiles/shell.rb +46 -0
- data/lib/circus/profiles.rb +10 -0
- data/lib/circus/repos/git.rb +42 -0
- data/lib/circus/repos/mercurial.rb +42 -0
- data/lib/circus/repos.rb +16 -0
- data/lib/circus/resource_allocator_client.rb +19 -0
- data/lib/circus/stdout_logger.rb +11 -0
- data/lib/circus/version.rb +3 -0
- data/lib/circus.rb +9 -0
- data/vendor/ruby-dbus/COPYING +504 -0
- data/vendor/ruby-dbus/ChangeLog +782 -0
- data/vendor/ruby-dbus/HOWTO-RELEASE +14 -0
- data/vendor/ruby-dbus/NEWS +104 -0
- data/vendor/ruby-dbus/README +53 -0
- data/vendor/ruby-dbus/Rakefile +47 -0
- data/vendor/ruby-dbus/doc/tutorial/src/00.index.page +12 -0
- data/vendor/ruby-dbus/doc/tutorial/src/10.intro.page +127 -0
- data/vendor/ruby-dbus/doc/tutorial/src/20.basic_client.page +174 -0
- data/vendor/ruby-dbus/doc/tutorial/src/30.service.page +121 -0
- data/vendor/ruby-dbus/doc/tutorial/src/default.css +129 -0
- data/vendor/ruby-dbus/doc/tutorial/src/default.template +46 -0
- data/vendor/ruby-dbus/examples/gdbus/gdbus +255 -0
- data/vendor/ruby-dbus/examples/gdbus/gdbus.glade +184 -0
- data/vendor/ruby-dbus/examples/gdbus/launch.sh +4 -0
- data/vendor/ruby-dbus/examples/no-introspect/nm-test.rb +21 -0
- data/vendor/ruby-dbus/examples/no-introspect/tracker-test.rb +16 -0
- data/vendor/ruby-dbus/examples/rhythmbox/playpause.rb +25 -0
- data/vendor/ruby-dbus/examples/service/call_service.rb +25 -0
- data/vendor/ruby-dbus/examples/service/service_newapi.rb +51 -0
- data/vendor/ruby-dbus/examples/simple/call_introspect.rb +34 -0
- data/vendor/ruby-dbus/examples/utils/listnames.rb +11 -0
- data/vendor/ruby-dbus/examples/utils/notify.rb +19 -0
- data/vendor/ruby-dbus/lib/dbus/auth.rb +156 -0
- data/vendor/ruby-dbus/lib/dbus/bus.rb +750 -0
- data/vendor/ruby-dbus/lib/dbus/export.rb +133 -0
- data/vendor/ruby-dbus/lib/dbus/introspect.rb +544 -0
- data/vendor/ruby-dbus/lib/dbus/marshall.rb +443 -0
- data/vendor/ruby-dbus/lib/dbus/matchrule.rb +100 -0
- data/vendor/ruby-dbus/lib/dbus/message.rb +293 -0
- data/vendor/ruby-dbus/lib/dbus/type.rb +222 -0
- data/vendor/ruby-dbus/lib/dbus.rb +89 -0
- data/vendor/ruby-dbus/ruby-dbus.gemspec +28 -0
- data/vendor/ruby-dbus/setup.rb +1585 -0
- data/vendor/ruby-dbus/test/Makefile +4 -0
- data/vendor/ruby-dbus/test/bus_driver_test.rb +21 -0
- data/vendor/ruby-dbus/test/server_robustness_test.rb +41 -0
- data/vendor/ruby-dbus/test/server_test.rb +44 -0
- data/vendor/ruby-dbus/test/service_newapi.rb +99 -0
- data/vendor/ruby-dbus/test/session_bus_test_manual.rb +20 -0
- data/vendor/ruby-dbus/test/signal_test.rb +57 -0
- data/vendor/ruby-dbus/test/t1 +4 -0
- data/vendor/ruby-dbus/test/t2.rb +66 -0
- data/vendor/ruby-dbus/test/t3-ticket27.rb +18 -0
- data/vendor/ruby-dbus/test/t5-report-dbus-interface.rb +58 -0
- data/vendor/ruby-dbus/test/t6-loop.rb +85 -0
- data/vendor/ruby-dbus/test/test_all +26 -0
- data/vendor/ruby-dbus/test/test_server +74 -0
- data/vendor/ruby-dbus/test/variant_test.rb +66 -0
- metadata +225 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'yaml'
|
3
|
+
require 'circus/external_util'
|
4
|
+
|
5
|
+
module Circus
|
6
|
+
module Profiles
|
7
|
+
PROFILES=[]
|
8
|
+
|
9
|
+
# Base functionality for an Profile
|
10
|
+
class Base
|
11
|
+
def initialize(name, dir, props)
|
12
|
+
@name = name
|
13
|
+
@dir = dir
|
14
|
+
@props = props
|
15
|
+
end
|
16
|
+
|
17
|
+
def package_base_dir?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def extra_dirs
|
22
|
+
[]
|
23
|
+
end
|
24
|
+
|
25
|
+
def package_for_dev(logger, run_dir)
|
26
|
+
return false unless prepare_for_dev(logger, run_dir)
|
27
|
+
write_run_script(run_dir) do |f|
|
28
|
+
f.write(dev_run_script_content.strip)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def package_for_deploy(logger, run_dir)
|
33
|
+
return false unless prepare_for_deploy(logger, run_dir)
|
34
|
+
write_run_script(run_dir) do |f|
|
35
|
+
f.write(deploy_run_script_content.strip)
|
36
|
+
end
|
37
|
+
File.open(File.join(run_dir, 'requirements.yaml'), 'w') do |f|
|
38
|
+
f.write(requirements.to_yaml)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def cleanup_after_deploy(logger, overlay_dir)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Overriden by subclasses to specify the resources that they require. Defaults to a resource
|
46
|
+
# hash provided in the act definition
|
47
|
+
def requirements
|
48
|
+
(@props['requirements'] || {}).dup
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
# Overriden by subclasses to handle development preparation. Defaults to the same as the deployment preparation.
|
53
|
+
def prepare_for_dev(logger, run_dir)
|
54
|
+
prepare_for_deploy(logger, run_dir)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Overriden by classes to handle generating the run script content for development.
|
58
|
+
def dev_run_script_content
|
59
|
+
end
|
60
|
+
|
61
|
+
# Overriden by subclasses to handle deployment preparation
|
62
|
+
def prepare_for_deploy(logger, run_dir)
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
# Overriden by classes to handle generating the run script content for deployment.
|
67
|
+
def deploy_run_script_content
|
68
|
+
end
|
69
|
+
|
70
|
+
def write_run_script(run_dir)
|
71
|
+
File.open(File.join(run_dir, 'run'), 'w') do |f|
|
72
|
+
yield f
|
73
|
+
end
|
74
|
+
File.chmod 0777, File.join(run_dir, 'run')
|
75
|
+
end
|
76
|
+
|
77
|
+
def shell_run_script
|
78
|
+
<<-EOT
|
79
|
+
#!/bin/sh
|
80
|
+
|
81
|
+
#{yield}
|
82
|
+
EOT
|
83
|
+
end
|
84
|
+
|
85
|
+
def write_dev_run_script(run_dir)
|
86
|
+
write_run_script(run_dir) do |f|
|
87
|
+
base_template = <<-EOT
|
88
|
+
#!/bin/sh
|
89
|
+
|
90
|
+
cd #{@dir}
|
91
|
+
EOT
|
92
|
+
|
93
|
+
f.write(base_template.lstrip)
|
94
|
+
yield f
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def write_deploy_run_script(run_dir)
|
99
|
+
write_run_script(run_dir) do |f|
|
100
|
+
base_template = <<-EOT
|
101
|
+
#!/bin/sh
|
102
|
+
|
103
|
+
EOT
|
104
|
+
|
105
|
+
f.write(base_template.lstrip)
|
106
|
+
yield f
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def run_external(logger, desc, cmd)
|
111
|
+
ExternalUtil.run_external(logger, desc, cmd)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.expand_path('../python_base', __FILE__)
|
2
|
+
|
3
|
+
module Circus
|
4
|
+
module Profiles
|
5
|
+
class Django < PythonBase
|
6
|
+
DJANGO_APP_PROPERTY='django-app'
|
7
|
+
|
8
|
+
# Checks if this is a Django application. Will accept the application if it
|
9
|
+
# has a file named manage.py, or has a 'django-app' property describing the entry point.
|
10
|
+
def self.accepts?(name, dir, props)
|
11
|
+
return true if props.include? DJANGO_APP_PROPERTY
|
12
|
+
return File.exists?(File.join(dir, "manage.py"))
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(name, dir, props)
|
16
|
+
super(name, dir, props)
|
17
|
+
|
18
|
+
@manage_script = props[DJANGO_APP_PROPERTY] || "manage.py"
|
19
|
+
end
|
20
|
+
|
21
|
+
# The name of this profile
|
22
|
+
def name
|
23
|
+
"django"
|
24
|
+
end
|
25
|
+
|
26
|
+
def prepare_for_deploy(logger, overlay_dir)
|
27
|
+
return false unless super
|
28
|
+
|
29
|
+
File.open(File.join(overlay_dir, 'local_settings.py'), 'w') do |f|
|
30
|
+
f.write <<-EOT
|
31
|
+
import os
|
32
|
+
|
33
|
+
DATABASE_ENGINE = 'postgresql_psycopg2'
|
34
|
+
DATABASE_NAME = os.getenv('DATABASE_NAME')
|
35
|
+
DATABASE_USER = os.getenv('DATABASE_USER')
|
36
|
+
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')
|
37
|
+
DATABASE_HOST = os.getenv('DATABASE_HOST')
|
38
|
+
EOT
|
39
|
+
end
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def dev_run_script_content
|
44
|
+
shell_run_script do
|
45
|
+
<<-EOT
|
46
|
+
cd #{@dir}
|
47
|
+
exec vendor/bin/python #{@manage_script} runserver
|
48
|
+
EOT
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def deploy_run_script_content
|
53
|
+
shell_run_script do
|
54
|
+
<<-EOT
|
55
|
+
exec vendor/bin/python #{@manage_script} runserver --noreload 0.0.0.0:$LISTEN_PORT
|
56
|
+
EOT
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Describes the requirements of the deployed application. Django applications automatically
|
61
|
+
# require a database with accessible credentials.
|
62
|
+
def requirements
|
63
|
+
res = super
|
64
|
+
|
65
|
+
db_name = @props['database_name'] || @name
|
66
|
+
res['resources'] ||= []
|
67
|
+
res['resources'] << {
|
68
|
+
'type' => 'Postgres',
|
69
|
+
'name' => db_name,
|
70
|
+
'user' => @props['database_user'] || db_name,
|
71
|
+
'password' => @props['database_password'] || db_name
|
72
|
+
}
|
73
|
+
|
74
|
+
# TODO: The clown should be able to automatically allocate listening ports
|
75
|
+
res['system-properties'] ||= {}
|
76
|
+
res['system-properties']['LISTEN_PORT'] = 3000
|
77
|
+
|
78
|
+
# TODO: The clown should be able to automatically respond with DB details
|
79
|
+
res['system-properties']['DATABASE_NAME'] = db_name
|
80
|
+
res['system-properties']['DATABASE_USER'] = db_name
|
81
|
+
res['system-properties']['DATABASE_PASSWORD'] = @props['database_password'] || db_name
|
82
|
+
res['system-properties']['DATABASE_HOST'] = 'localhost'
|
83
|
+
|
84
|
+
res
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
PROFILES << Django
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.expand_path('../base', __FILE__)
|
2
|
+
|
3
|
+
module Circus
|
4
|
+
module Profiles
|
5
|
+
class Jekyll < Base
|
6
|
+
# Checks if this is a Jekyll site based on whether there is a file named
|
7
|
+
# _config.yml on the root directory
|
8
|
+
def self.accepts?(name, dir, props)
|
9
|
+
return File.exists?(File.join(dir, "_config.yml"))
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(name, dir, props)
|
13
|
+
super(name, dir, props)
|
14
|
+
end
|
15
|
+
|
16
|
+
# The name of this profile
|
17
|
+
def name
|
18
|
+
"jekyll"
|
19
|
+
end
|
20
|
+
|
21
|
+
def package_base_dir?
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
def extra_dirs
|
26
|
+
["#{@dir}/_site"]
|
27
|
+
end
|
28
|
+
|
29
|
+
def prepare_for_deploy(logger, overlay_dir)
|
30
|
+
run_external(logger, 'Generate site with Jekyll', "cd #{@dir}; jekyll")
|
31
|
+
|
32
|
+
# Create lighttpd.conf
|
33
|
+
File.open(File.join(overlay_dir, 'lighttpd.conf'), 'w') do |f|
|
34
|
+
f.write <<-EOT
|
35
|
+
server.document-root = "_site/"
|
36
|
+
|
37
|
+
server.port = env.HTTPD_PORT
|
38
|
+
|
39
|
+
mimetype.assign = (
|
40
|
+
".html" => "text/html",
|
41
|
+
".txt" => "text/plain",
|
42
|
+
".css" => "text/css",
|
43
|
+
".jpg" => "image/jpeg",
|
44
|
+
".png" => "image/png"
|
45
|
+
)
|
46
|
+
|
47
|
+
static-file.exclude-extensions = ( ".yaml" )
|
48
|
+
index-file.names = ( "index.html" )
|
49
|
+
EOT
|
50
|
+
end
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
def cleanup_after_deploy(logger, overlay_dir)
|
55
|
+
FileUtils.rm_rf(File.join(@dir, '_site'))
|
56
|
+
end
|
57
|
+
|
58
|
+
def dev_run_script_content
|
59
|
+
shell_run_script do
|
60
|
+
<<-EOT
|
61
|
+
cd #{@dir}
|
62
|
+
exec jekyll --auto --server
|
63
|
+
EOT
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def deploy_run_script_content
|
68
|
+
shell_run_script do
|
69
|
+
<<-EOT
|
70
|
+
exec lighttpd -D -f lighttpd.conf
|
71
|
+
EOT
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Describes the resources required by the deployed application. Jekyll sites automatically
|
76
|
+
# require a port to serve content on.
|
77
|
+
def requirements
|
78
|
+
res = super
|
79
|
+
|
80
|
+
# TODO: The clown should be able to automatically allocate listening ports
|
81
|
+
res['system-properties'] ||= {}
|
82
|
+
res['system-properties']['HTTPD_PORT'] = 3000
|
83
|
+
|
84
|
+
res
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
PROFILES << Jekyll
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path('../base', __FILE__)
|
2
|
+
|
3
|
+
module Circus
|
4
|
+
module Profiles
|
5
|
+
class MakeBase < Base
|
6
|
+
# Development preparation is the same as deployment
|
7
|
+
def prepare_for_dev(logger, run_dir)
|
8
|
+
prepare_for_deploy(logger, run_dir)
|
9
|
+
end
|
10
|
+
|
11
|
+
def prepare_for_deploy(logger, overlay_dir)
|
12
|
+
# Build the application
|
13
|
+
run_external(logger, 'Compile application', "cd #{@dir}; make")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path('../python_base', __FILE__)
|
2
|
+
|
3
|
+
module Circus
|
4
|
+
module Profiles
|
5
|
+
class PurePy < PythonBase
|
6
|
+
PUREPY_APP_PROPERTY='purepy-app'
|
7
|
+
|
8
|
+
# Checks if this is a pure python application. Will accept the application if it
|
9
|
+
# has a file named <name>.py, or has a 'purepy-app' property describing the entry point.
|
10
|
+
def self.accepts?(name, dir, props)
|
11
|
+
return true if props.include? PUREPY_APP_PROPERTY
|
12
|
+
return File.exists?(File.join(dir, "#{name}.py"))
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(name, dir, props)
|
16
|
+
super(name, dir, props)
|
17
|
+
|
18
|
+
@py_script = props[PUREPY_APP_PROPERTY] || "#{name}.py"
|
19
|
+
end
|
20
|
+
|
21
|
+
# The name of this profile
|
22
|
+
def name
|
23
|
+
"pure-py"
|
24
|
+
end
|
25
|
+
|
26
|
+
def dev_run_script_content
|
27
|
+
shell_run_script do
|
28
|
+
<<-EOT
|
29
|
+
cd #{@dir}
|
30
|
+
exec vendor/bin/python #{@py_script}
|
31
|
+
EOT
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def deploy_run_script_content
|
36
|
+
shell_run_script do
|
37
|
+
<<-EOT
|
38
|
+
exec vendor/bin/python #{@py_script}
|
39
|
+
EOT
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
PROFILES << PurePy
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../ruby_base', __FILE__)
|
2
|
+
|
3
|
+
module Circus
|
4
|
+
module Profiles
|
5
|
+
class PureRb < RubyBase
|
6
|
+
PURERB_APP_PROPERTY='purerb-app'
|
7
|
+
|
8
|
+
# Checks if this is a pure ruby application. Will accept the application if it
|
9
|
+
# has a file named <name>.rb, or has a 'purerb-app' property describing the entry point.
|
10
|
+
def self.accepts?(name, dir, props)
|
11
|
+
return true if props.include? PURERB_APP_PROPERTY
|
12
|
+
return File.exists?(File.join(dir, "#{name}.rb"))
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(name, dir, props)
|
16
|
+
super(name, dir, props)
|
17
|
+
|
18
|
+
@rb_script = props[PURERB_APP_PROPERTY] || "#{name}.rb"
|
19
|
+
end
|
20
|
+
|
21
|
+
# The name of this profile
|
22
|
+
def name
|
23
|
+
"pure-rb"
|
24
|
+
end
|
25
|
+
|
26
|
+
# Just run the script in development
|
27
|
+
def dev_run_script_content
|
28
|
+
shell_run_script do
|
29
|
+
<<-EOT
|
30
|
+
cd #{@dir}
|
31
|
+
exec ruby #{@rb_script}
|
32
|
+
EOT
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Install our gems and then run in deployment
|
37
|
+
def deploy_run_script_content
|
38
|
+
shell_run_script do
|
39
|
+
<<-EOT
|
40
|
+
exec ruby #{@rb_script}
|
41
|
+
EOT
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
PROFILES << PureRb
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path('../base', __FILE__)
|
2
|
+
|
3
|
+
module Circus
|
4
|
+
module Profiles
|
5
|
+
class PythonBase < Base
|
6
|
+
# Development preparation is the same as deployment
|
7
|
+
def prepare_for_dev(logger, run_dir)
|
8
|
+
prepare_for_deploy(logger, run_dir)
|
9
|
+
end
|
10
|
+
|
11
|
+
def prepare_for_deploy(logger, overlay_dir)
|
12
|
+
# Build the virtualenv
|
13
|
+
if has_depsfile?
|
14
|
+
unless File.exists? "#{@dir}/vendor"
|
15
|
+
return false unless run_external(logger, "Create virtualenv", "cd #{@dir}; virtualenv --no-site-packages vendor")
|
16
|
+
end
|
17
|
+
|
18
|
+
File.read(depsfile_fn).lines.each do |dep|
|
19
|
+
return false unless run_external(logger, "Install dep #{dep}",
|
20
|
+
"cd #{@dir}; vendor/bin/easy_install -q \"#{dep.strip}\"")
|
21
|
+
end
|
22
|
+
|
23
|
+
return false unless run_external(logger, "Make virtualenv relocatable", "cd #{@dir}; virtualenv --relocatable vendor")
|
24
|
+
end
|
25
|
+
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
def depsfile_fn
|
31
|
+
"#{@dir}/Pydeps"
|
32
|
+
end
|
33
|
+
|
34
|
+
def has_depsfile?
|
35
|
+
File.exists? depsfile_fn
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path('../ruby_base', __FILE__)
|
2
|
+
|
3
|
+
module Circus
|
4
|
+
module Profiles
|
5
|
+
class Rack < RubyBase
|
6
|
+
RACKFILE_NAME='ruby-rackfile'
|
7
|
+
|
8
|
+
# Checks if this is a rack applcation. Will accept the application if it has a config.ru, or if the
|
9
|
+
# properties describe the location of an alternative rack entry point.
|
10
|
+
def self.accepts?(name, dir, props)
|
11
|
+
return true if props.include? RACKFILE_NAME
|
12
|
+
return File.exists?(File.join(dir, 'config.ru'))
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(name, dir, props)
|
16
|
+
super(name, dir, props)
|
17
|
+
|
18
|
+
@rackup_name = props[RACKFILE_NAME] || 'config.ru'
|
19
|
+
end
|
20
|
+
|
21
|
+
# The name of this profile
|
22
|
+
def name
|
23
|
+
"rack"
|
24
|
+
end
|
25
|
+
|
26
|
+
def dev_run_script_content
|
27
|
+
shell_run_script do
|
28
|
+
<<-EOT
|
29
|
+
cd #{@dir}
|
30
|
+
exec bundle exec thin -R #{@rackup_name} -p #{listen_port} start
|
31
|
+
EOT
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def deploy_run_script_content
|
36
|
+
shell_run_script do
|
37
|
+
<<-EOT
|
38
|
+
exec bundle exec vendor/bin/thin -R #{@rackup_name} -p #{listen_port} start
|
39
|
+
EOT
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def extra_dirs
|
44
|
+
if has_gemfile?
|
45
|
+
["#{@dir}/.bundle"]
|
46
|
+
else
|
47
|
+
[]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def listen_port
|
53
|
+
@props['web-app-port'] || 3000
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
PROFILES << Rack
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path('../base', __FILE__)
|
2
|
+
require 'fileutils'
|
3
|
+
require 'bundler/circus_util'
|
4
|
+
|
5
|
+
module Circus
|
6
|
+
module Profiles
|
7
|
+
class RubyBase < Base
|
8
|
+
BUNDLER_TOOL=File.expand_path('../../../bundler/circus_bundler.rb', __FILE__)
|
9
|
+
|
10
|
+
def initialize(name, dir, props)
|
11
|
+
super(name, dir, props)
|
12
|
+
end
|
13
|
+
|
14
|
+
# No dev preparation required. Don't override dev_run_script_content, since it is the
|
15
|
+
# same as the deployment variant.
|
16
|
+
def prepare_for_dev(logger, run_dir); true; end
|
17
|
+
|
18
|
+
def prepare_for_deploy(logger, overlay_dir)
|
19
|
+
# Run the gem bundler if necessary
|
20
|
+
if has_gemfile?
|
21
|
+
logger.info("Bundling gems")
|
22
|
+
run_external(logger, 'gem bundling', "cd #{@dir}; ruby #{BUNDLER_TOOL}")
|
23
|
+
end
|
24
|
+
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def cleanup_after_deploy(logger, overlay_dir)
|
29
|
+
Bundler::CircusUtil.unfix_external_paths(@dir)
|
30
|
+
end
|
31
|
+
|
32
|
+
def extra_dirs
|
33
|
+
if has_gemfile?
|
34
|
+
["#{@dir}/.bundle"]
|
35
|
+
else
|
36
|
+
[]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
def has_gemfile?
|
42
|
+
File.exists? "#{@dir}/Gemfile"
|
43
|
+
end
|
44
|
+
|
45
|
+
# class LoggingShell
|
46
|
+
# def say(msg)
|
47
|
+
# puts msg
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path('../make_base', __FILE__)
|
2
|
+
|
3
|
+
module Circus
|
4
|
+
module Profiles
|
5
|
+
class Shell < MakeBase
|
6
|
+
SHELL_APP_PROPERTY='shell-app'
|
7
|
+
|
8
|
+
# Checks if this is a shell applcation. Will accept the application if it
|
9
|
+
# has a file named <name>.sh, or has a 'shell-app' property describing the entry point.
|
10
|
+
def self.accepts?(name, dir, props)
|
11
|
+
return true if props.include? SHELL_APP_PROPERTY
|
12
|
+
return File.exists?(File.join(dir, "#{name}.sh"))
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(name, dir, props)
|
16
|
+
super(name, dir, props)
|
17
|
+
|
18
|
+
@sh_script = props[SHELL_APP_PROPERTY] || "#{name}.sh"
|
19
|
+
end
|
20
|
+
|
21
|
+
# The name of this profile
|
22
|
+
def name
|
23
|
+
"shell"
|
24
|
+
end
|
25
|
+
|
26
|
+
def dev_run_script_content
|
27
|
+
shell_run_script do
|
28
|
+
<<-EOT
|
29
|
+
cd #{@dir}
|
30
|
+
exec sh #{@sh_script}
|
31
|
+
EOT
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def deploy_run_script_content
|
36
|
+
shell_run_script do
|
37
|
+
<<-EOT
|
38
|
+
exec sh #{@sh_script}
|
39
|
+
EOT
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
PROFILES << Shell
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.expand_path('../profiles/base', __FILE__)
|
2
|
+
require File.expand_path('../profiles/ruby_base', __FILE__)
|
3
|
+
require File.expand_path('../profiles/rack', __FILE__)
|
4
|
+
require File.expand_path('../profiles/pure_rb', __FILE__)
|
5
|
+
require File.expand_path('../profiles/python_base', __FILE__)
|
6
|
+
require File.expand_path('../profiles/pure_py', __FILE__)
|
7
|
+
require File.expand_path('../profiles/make_base', __FILE__)
|
8
|
+
require File.expand_path('../profiles/shell', __FILE__)
|
9
|
+
require File.expand_path('../profiles/django', __FILE__)
|
10
|
+
require File.expand_path('../profiles/jekyll', __FILE__)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Circus
|
2
|
+
module Repos
|
3
|
+
class Git
|
4
|
+
# Checks if the current directory (or a parent) are Git working trees. Uses
|
5
|
+
# a call to git remote to test (which will fail with a non-zero exit if the
|
6
|
+
# tree isn't a valid git tree)
|
7
|
+
def self.accepts_dir? dir_name
|
8
|
+
`git remote >/dev/null 2>/dev/null`
|
9
|
+
$? == 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.accepts_id?(key)
|
13
|
+
key == 'git'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.type_id
|
17
|
+
'git'
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(dir)
|
21
|
+
@dir = dir
|
22
|
+
end
|
23
|
+
|
24
|
+
def repo_url
|
25
|
+
first_remote = `(cd #{@dir}; git remote -v) | grep fetch`.lines.first
|
26
|
+
return nil unless first_remote
|
27
|
+
|
28
|
+
first_remote.split(' ', 2)[1].gsub('(fetch)', '').strip
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_revision
|
32
|
+
`(cd #{@dir}; git rev-parse HEAD)`.strip
|
33
|
+
end
|
34
|
+
|
35
|
+
def write_patch(patch_fn)
|
36
|
+
`(cd #{@dir}; git diff HEAD >#{patch_fn})`.strip
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
REPOS << Git
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Circus
|
2
|
+
module Repos
|
3
|
+
class Mercurial
|
4
|
+
# Checks if the current directory (or a parent) are Hg working trees. Uses
|
5
|
+
# a call to hg status to test (which will fail with a non-zero exit if the
|
6
|
+
# tree isn't a valid git tree)
|
7
|
+
def self.accepts_dir? dir_name
|
8
|
+
`hg st >/dev/null 2>/dev/null`
|
9
|
+
$? == 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.accepts_id?(key)
|
13
|
+
key == 'hg' || key == 'mercurial'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.type_id
|
17
|
+
'hg'
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(dir)
|
21
|
+
@dir = dir
|
22
|
+
end
|
23
|
+
|
24
|
+
def repo_url
|
25
|
+
first_path = `(cd #{@dir}; hg paths)`.lines.first
|
26
|
+
return nil unless first_path
|
27
|
+
|
28
|
+
first_path.split('=', 2)[1].strip
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_revision
|
32
|
+
`(cd #{@dir}; hg id -i)`[0..11]
|
33
|
+
end
|
34
|
+
|
35
|
+
def write_patch(patch_fn)
|
36
|
+
`(cd #{@dir}; hg diff >#{patch_fn})`.strip
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
REPOS << Mercurial
|
41
|
+
end
|
42
|
+
end
|