cheese 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
File without changes
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2007 Jamie van Dyke
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,30 @@
1
+ CHANGELOG.txt
2
+ History.txt
3
+ LICENSE
4
+ Manifest.txt
5
+ README.txt
6
+ Rakefile
7
+ setup.rb
8
+ TODO.txt
9
+
10
+ bin/cheese
11
+
12
+ data/templates/footer.inc
13
+ data/templates/header.inc
14
+ data/templates/mongrel.inc
15
+ data/templates/proxy.inc
16
+ data/templates/vhost.inc
17
+
18
+ lib/cheese-setup.rb
19
+ lib/controller.rb
20
+ lib/process.rb
21
+ lib/verbose.rb
22
+ lib/cheese/version.rb
23
+ lib/database/mysql.rb
24
+ lib/database/postgresql.rb
25
+ lib/scm/subversion.rb
26
+ lib/web/domain.rb
27
+ lib/web/mongrel.rb
28
+ lib/web/nginx.rb
29
+ lib/web/proxy.rb
30
+ lib/web/virtual_host.rb
@@ -0,0 +1,132 @@
1
+ == Cheese
2
+
3
+ Cheese is a set of ruby scripts supplied with all Candid Mush
4
+ Virtual Cheesey Servers but available to all under the MIT license.
5
+ They reduce the steps needed to administrate a web server.
6
+
7
+ Currently this script is executed server side, but we're looking
8
+ into using Capistrano to manage it instead.
9
+
10
+ Cheese Tools can:
11
+
12
+ * Add nginx virtual hosts
13
+ * Replace nginx virtual hosts
14
+ * Remove nginx virtual hosts
15
+ * Create subversion repositories
16
+ * Remove subversion repositories
17
+ * Set access rights on subversion repositories
18
+ * Create mysql/pgsql databases
19
+ * Delete mysql/pgsql databases
20
+
21
+ Cheese Tools will be able to:
22
+
23
+ * Configure monit to watch your sites and svnserve
24
+ * Configure a scheduled backup of your sites and source to s3
25
+
26
+
27
+ == Requirements
28
+
29
+ Gems:
30
+ * Rubygems
31
+ * OptionParser
32
+ * Highline
33
+
34
+ Nginx Config
35
+ If you are using this on an existing nginx.conf file, you must wrap your vhosts like so:
36
+
37
+ #### VHOST something.com BEGIN ####
38
+ server {
39
+ ...
40
+ }
41
+ #### VHOST something.com END ####
42
+
43
+ #### PROXY something.com BEGIN ####
44
+ upstream something_com_mongrel {
45
+ ...
46
+ }
47
+ #### PROXY something.com END ####
48
+
49
+ and the proxies that each use like so:
50
+
51
+
52
+ This is temporary until I improve my regex skills somewhat, or someone
53
+ changes it for me.
54
+
55
+ == Setup
56
+
57
+ Before you can use Cheese you need to run cheese --setup, you will be
58
+ notified of this if you forget, however, this can be re-run if you
59
+ wish to change any options you have previously set.
60
+
61
+ The Cheese setup utility:
62
+
63
+ * Asks what type of setup you have (out of the supported sets)
64
+ * Saves a default source code management username and password
65
+
66
+
67
+
68
+ == Switches
69
+
70
+ -L or --list-vhosts
71
+ List the vhosts contained in the /etc/nginx/nginx.conf file
72
+
73
+ --setup
74
+ Run the setup utility which saves preferences to /etc/cheese/cheese.conf
75
+
76
+ --domain domain-name.com
77
+ Set the domain name to use
78
+ --mongrel-threads
79
+ Let Cheese Tools know how many threads you want to run
80
+
81
+ --remove
82
+ Remove this vhost and the subversion repository
83
+
84
+ --svn-read-all
85
+ Set svnserve to allow anonymous read on the subversion repository
86
+
87
+ --pgsql
88
+ Use PostgreSQL instead of MySQL which is the default
89
+
90
+ --skip-nginx
91
+ Don't add a vhost or restart nginx
92
+ --skip-svn
93
+ Don't create a subversion repository or attempt to add files to one
94
+ --skip-mongrel-config
95
+ Don't create a mongrel_cluster.yml config file
96
+ --skip-database
97
+ Don't create the database
98
+ --only-nginx
99
+ Only add/replace a vhost and restart nginx
100
+ --only-svn
101
+ Only create a subversion repository and standard file structure
102
+ --only-mongrel-config
103
+ Only create a mongrel_cluster.yml config file
104
+ --only-database
105
+ Only create the database
106
+
107
+ == Usage
108
+
109
+ To create a new web application with a subversion repository which stores
110
+ the source and a mongrel_cluster config:
111
+
112
+ ./cheese --domain candidmush.com --mongrel-threads 2
113
+
114
+ The steps cheese will take are:
115
+
116
+ * Add a vhost to /etc/nginx/nginx.conf
117
+ * Add a mongrel proxy declaration to /etc/nginx/nginx.conf
118
+ * Create a subversion repository in /var/src/candidmush.com
119
+ * The standard structure of branches/tags/trunk will be added
120
+ * Add a Cap config file to trunk/config/deploy.rb
121
+ * Add a mongrel_cluster config to trunk/config/mongrel_cluster.yml
122
+ * Start mongrel_cluster for this server
123
+ * Restart nginx
124
+
125
+
126
+ == Details
127
+
128
+ The port range to use for mongrel_cluster will be determined by finding
129
+ the highest port range used by other vhosts and incrementing it by 10.
130
+
131
+ If the vhost in nginx for the domain you are adding already exists,
132
+ Cheese Tools will replace it rather than add another.
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'cheese', 'version')
13
+
14
+ AUTHOR = "Jamie van Dyke"
15
+ EMAIL = "jamie@writtenpath.com"
16
+ DESCRIPTION = "Automate the creation of web applications and accompanying pieces e.g. Nginx, Subversion, Mongrel, Monit, S3."
17
+ GEM_NAME = "cheese"
18
+ RUBYFORGE_PROJECT = "cheese"
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+
21
+
22
+ NAME = "cheese"
23
+ REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
+ VERS = ENV['VERSION'] || (Cheese::VERSION::STRING + (REV ? ".#{REV}" : ""))
25
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
26
+ RDOC_OPTS = ['--quiet', '--title', "cheese documentation",
27
+ "--opname", "index.html",
28
+ "--line-numbers",
29
+ "--main", "README",
30
+ "--inline-source"]
31
+
32
+ class Hoe
33
+ def extra_deps
34
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
35
+ end
36
+ end
37
+
38
+ # Generate all the Rake tasks
39
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
40
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
41
+ p.author = AUTHOR
42
+ p.description = DESCRIPTION
43
+ p.email = EMAIL
44
+ p.summary = DESCRIPTION
45
+ p.url = HOMEPATH
46
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
47
+ p.test_globs = ["test/**/*_test.rb"]
48
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
49
+
50
+ # == Optional
51
+ #p.changes - A description of the release's latest changes.
52
+ p.extra_deps = ['highline', ">= 1.2.0"]
53
+ #p.spec_extras - A hash of extra values to set in the gemspec.
54
+ end
@@ -0,0 +1,11 @@
1
+ Things to implement in order of priority:
2
+
3
+ * TESTS TESTS TESTS!
4
+ * Monit services
5
+ * S3 backup
6
+ * Allow mongrel to use a set port
7
+ * Remove the parsing of the entire nginx file and use includes
8
+
9
+ Things to look into:
10
+
11
+ * Using Capistrano to manage this remotely
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ require 'rubygems'
5
+ require 'optparse'
6
+ require 'fileutils'
7
+
8
+ class Arguments < Hash
9
+ def initialize(args)
10
+ super
11
+
12
+ opts = OptionParser.new do |opts|
13
+ opts.banner = "Usage: #$0 [options]"
14
+
15
+ self[:setup] = false
16
+ self[:actions] = [:scm, :web_server, :app_server, :database]
17
+ self[:thread_count] = 1
18
+ self[:database_type] = :postgresql
19
+ self[:remove] = false
20
+ self[:svn_anon_read] = false
21
+ self[:verbose] = false
22
+ self[:dry_run] = false
23
+
24
+ opts.on('-n STRING', '--name STRING', String, '[REQUIRED] set the name to use') do |name|
25
+ self[:name] = name
26
+ end
27
+
28
+ opts.on('--setup', 'setup your preferences') do
29
+ self[:setup] = true
30
+ end
31
+
32
+ opts.on('--remove', 'remove instead of create') do
33
+ self[:remove] = true
34
+ end
35
+
36
+ opts.on('-t NUMBER', '--threads NUMBER', Integer,
37
+ '[DEFAULT=1] how many app server threads to listen on') do |thread_count|
38
+ self[:thread_count] = thread_count
39
+ end
40
+
41
+ opts.on('--scm-anon-read', 'set the scm to allow anonymous read on the source repository') do |anon|
42
+ self[:scm_anon_read] = anon
43
+ end
44
+
45
+ opts.on('-D', '--database-type STRING', [:mysql, :postgresql],
46
+ 'pass in the database type, currently { mysql || postgresql (default) }') do |dtype|
47
+ self[:database_type] = dtype
48
+ end
49
+
50
+ opts.on('--only-web-server', 'only add/replace a vhost and restart the web server (e.g. nginx)') do
51
+ self[:actions] = [:web_server]
52
+ end
53
+
54
+ opts.on('--only-scm', 'only create a scm repository and standard file structure') do
55
+ self[:actions] = [:scm]
56
+ end
57
+
58
+ opts.on('--only-app-config', 'only create an app server config file') do
59
+ self[:actions] = [:app_server]
60
+ end
61
+
62
+ opts.on('--only-database', 'only create the database') do
63
+ self[:actions] = [:database]
64
+ end
65
+
66
+ opts.on('--skip-web-server', 'skip adding/replacing a vhost and restarting the web server (e.g. nginx)') do
67
+ self[:actions] -= [:web_server]
68
+ end
69
+
70
+ opts.on('--skip-scm',
71
+ 'skip creating a source repository and standard file structure') do
72
+ self[:actions] -= [:scm]
73
+ end
74
+
75
+ opts.on('--skip-app-config', 'skip creating an app server config file') do
76
+ self[:actions] -= [:app_server]
77
+ end
78
+
79
+ opts.on('--skip-database', 'skip creating the database') do
80
+ self[:actions] -= [:database]
81
+ end
82
+
83
+ opts.on('-L', '--list-vhosts', 'list the vhosts contained in our web server') do
84
+ self[:actions] = [:list_vhosts]
85
+ end
86
+
87
+ opts.on_tail('-v', '--verbose', 'be verbose about what action is being taken') do
88
+ self[:verbose] = true
89
+ end
90
+
91
+ opts.on_tail('--dry-run', 'fake all of the actions') do
92
+ self[:dry_run] = true
93
+ end
94
+
95
+ opts.on_tail('-h', '--help', 'display this help and exit') do
96
+ puts opts
97
+ exit
98
+ end
99
+ end
100
+
101
+ opts.parse!(args)
102
+ if self[:name].empty? and !self[:list_vhosts]
103
+ puts "You must specify a name with the --name switch e.g. your-domain.com"
104
+ exit
105
+ end
106
+ end
107
+ end
108
+
109
+ # Default arguments to help if no arguments given
110
+ argv = ARGV.empty? ? ["-h"] : ARGV
111
+ options = Arguments.new(argv)
112
+
113
+ if options[:setup]
114
+ require 'cheese-setup'
115
+ else
116
+ require 'controller'
117
+ controller = Cheese::Controller.new(options)
118
+ end
@@ -0,0 +1 @@
1
+ }
@@ -0,0 +1,46 @@
1
+ user www-data;
2
+ worker_processes 3;
3
+
4
+ error_log /var/log/nginx/error.log;
5
+ pid /var/run/nginx.pid;
6
+
7
+ events {
8
+ worker_connections 1024;
9
+ }
10
+
11
+
12
+ # start the http module where we config http access.
13
+ http {
14
+ # pull in mime-types. You can break out your config
15
+ # into as many include's as you want to make it cleaner
16
+ include /etc/nginx/mime.types;
17
+
18
+ # set a default type for the rare situation that
19
+ # nothing matches from the mimie-type include
20
+ default_type application/octet-stream;
21
+
22
+ # configure log format
23
+ log_format main '$remote_addr - $remote_user [$time_local] $status '
24
+ '"$request" $body_bytes_sent "$http_referer" '
25
+ '"$http_user_agent" "$http_x_forwarded_for"';
26
+
27
+ # main access log
28
+ access_log /var/log/nginx_access.log main;
29
+
30
+ # main error log
31
+ error_log /var/log/nginx_error.log debug;
32
+
33
+ sendfile on;
34
+
35
+ # increase the url length limit
36
+ server_names_hash_bucket_size 128;
37
+
38
+ # These are good default values.
39
+ tcp_nopush on;
40
+ tcp_nodelay off;
41
+ # output compression saves bandwidth
42
+ gzip on;
43
+ gzip_http_version 1.0;
44
+ gzip_comp_level 2;
45
+ gzip_proxied any;
46
+ gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
@@ -0,0 +1,7 @@
1
+ ---
2
+ log_file: /var/www/||DOMAIN||/shared/log/production.log
3
+ port: "||PORT||"
4
+ environment: production
5
+ address: 127.0.0.1
6
+ pid_file: /var/www/||DOMAIN||/shared/tmp/pids/mongrel.pid
7
+ servers: ||THREADS||
@@ -0,0 +1,3 @@
1
+ upstream ||DOMAIN||_mongrel {
2
+ ||THREADS||
3
+ }
@@ -0,0 +1,84 @@
1
+ server {
2
+ # port to listen on. Can also be set to an IP:PORT
3
+ listen 80;
4
+
5
+ # Set the max size for file uploads to 50Mb
6
+ client_max_body_size 50M;
7
+
8
+ # sets the domain[s] that this vhost server requests for
9
+ server_name ||DOMAIN|| www.||DOMAIN||;
10
+
11
+ # redirect blank to www
12
+ if ($host != 'www.||DOMAIN||' ) {
13
+ rewrite ^/(.*)$ http://www.||DOMAIN||/$1 permanent;
14
+ }
15
+
16
+ # doc root
17
+ root /var/www/||DOMAIN||/current/public;
18
+
19
+ # vhost specific access log
20
+ access_log /var/log/nginx_||DOMAIN||.access.log main;
21
+
22
+
23
+ # this rewrites all the requests to the maintenance.html
24
+ # page if it exists in the doc root. This is for capistrano's
25
+ # disable web task
26
+ if (-f $document_root/system/maintenance.html) {
27
+ rewrite ^(.*)$ /system/maintenance.html last;
28
+ break;
29
+ }
30
+
31
+ location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|mov).*?$ {
32
+ root /var/www/||SHORT_DOMAIN||/current/public;
33
+ if (!-f $request_filename) {
34
+ proxy_pass http://||PROXY||_mongrel;
35
+ break;
36
+ }
37
+ }
38
+
39
+ location / {
40
+ # needed to forward user's IP address to rails
41
+ proxy_set_header X-Real-IP $remote_addr;
42
+
43
+ # needed for HTTPS
44
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
45
+ proxy_set_header Host $http_host;
46
+ proxy_redirect false;
47
+ proxy_max_temp_file_size 0;
48
+
49
+ # If the file exists as a static file serve it directly without
50
+ # running all the other rewite tests on it
51
+ if (-f $request_filename) {
52
+ break;
53
+ }
54
+
55
+ # check for index.html for directory index
56
+ # if its there on the filesystem then rewite
57
+ # the url to add /index.html to the end of it
58
+ # and then break to send it to the next config rules.
59
+ if (-f $request_filename/index.html) {
60
+ rewrite (.*) $1/index.html break;
61
+ }
62
+
63
+ # this is the meat of the rails page caching config
64
+ # it adds .html to the end of the url and then checks
65
+ # the filesystem for that file. If it exists, then we
66
+ # rewite the url to have explicit .html on the end
67
+ # and then send it on its way to the next config rule.
68
+ # if there is no file on the fs then it sets all the
69
+ # necessary headers and proxies to our upstream mongrels
70
+ if (-f $request_filename.html) {
71
+ rewrite (.*) $1.html break;
72
+ }
73
+
74
+ if (!-f $request_filename) {
75
+ proxy_pass http://||PROXY||_mongrel;
76
+ break;
77
+ }
78
+ }
79
+
80
+ error_page 500 502 503 504 /500.html;
81
+ location = /500.html {
82
+ root /var/www/||DOMAIN||/current/public;
83
+ }
84
+ }