circus-deployment 0.0.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/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
|