plow 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ .yardoc
7
+ doc
8
+ plow.gemspec
9
+ plow.tmproj
data/.yardopts ADDED
@@ -0,0 +1,6 @@
1
+ --markup markdown
2
+ --private
3
+ -
4
+ LICENSE
5
+ HISTORY
6
+ SECURITY
data/HISTORY ADDED
@@ -0,0 +1,39 @@
1
+ == 1.0.0 released on Oct. ??th 2009
2
+
3
+ * bin/plow and bin/plow1.9
4
+ * Two ruby 1.9.1 compatible command-line executables.
5
+ * Combined with Plow::Application, the entire application logic is decoupled from the plow generator library.
6
+ * lib/plow.rb
7
+ * Handles load-time errors gracefully for the user
8
+ * Specifies library-wide load order
9
+ * Maintains the library version in memory
10
+ * lib/plow/application.rb
11
+ * decoupled argument parsing from the generator
12
+ * displays usage for the command-line executables
13
+ * handles run-time errors gracefully for the user
14
+ * starts the generator
15
+ * Combined with the executables, the entire application logic is decoupled from the plow generator library.
16
+ * lib/plow/generator.rb
17
+ * main controller
18
+ * maintains the shared state data including a strategy object
19
+ * passes execution to the strategy object
20
+ * provides shared logic for outputting messages to the user
21
+ * provides shared logic for executing shell commands
22
+ * provides shared logic for evaluating ERB template files
23
+ * lib/plow/binding_struct.rb
24
+ * helper object that converts a Hash object into instances variables, which then is used as the binding object for ERB
25
+ * lib/plow/core_ext/object.rb
26
+ * dynamically adds a #blank? method to all objects (copied directly from the active_support library)
27
+ * lib/plow/errors.rb
28
+ * defines a handful of run-time error classes
29
+ * lib/plow/strategy/ubuntu_hardy/user_home_web_app.rb
30
+ * userhome-based strategy for generating a system-wide web-site structure for the Linux Ubuntu Hardy 8.04.3 LTS operating system
31
+ * understanding and managing the security implications of web server of virtual hosts
32
+ * lib/plow/strategy/ubuntu_hardy/templates/apache2-vhost.conf
33
+ * a simple apache2 virtual host ERB template file for the Linux Ubuntu Hardy 8.04.3 LTS operating system
34
+ * lib/plow/strategy/ubuntu_hardy/templates/README.txt
35
+ * a README file that explains the generated web-site directory structure and files
36
+ * Rakefile
37
+ * incorporating deployments with jeweler and gemcutter. the combination is extremely powerful and seems alot more practical than maintaining my own rubygem server.
38
+
39
+ * inviting others to review my code and submitting patches! long live the open-source community!
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Ryan Sobol
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,152 @@
1
+ ![Following the Plow](http://img.skitch.com/20091010-jd9m46i9g5u4fyyprkfe36p4q9.gif)
2
+
3
+ Image courtesy of [Mother Earth News](http://www.motherearthnews.com/Modern-Homesteading/1974-05-01/Walking-Plow.aspx)
4
+
5
+ PLOW Release 0.1.0 (October 13th 2009)
6
+ ======================================
7
+
8
+ Copyright © 2009 Ryan Sobol. Licensed under the MIT license. Please see the {file:LICENSE} for more information.
9
+
10
+ **Homepage**: [http://github.com/ryansobol/plow](http://github.com/ryansobol/plow)
11
+
12
+ **Documentation**: [http://rdoc.info/projects/ryansobol/plow](http://rdoc.info/projects/ryansobol/plow)
13
+ **Code Metrics**: [http://devver.net/caliper/project?repo=git%3A%2F%2Fgithub.com%2Fryansobol%2Fplow.git](http://devver.net/caliper/project?repo=git%3A%2F%2Fgithub.com%2Fryansobol%2Fplow.git)
14
+
15
+ WHAT'S NEW?
16
+ -----------
17
+
18
+ **v0.1.0**
19
+
20
+ * Canonical 'plow' namespace reserved on [Gemcutter](http://gemcutter.org/gems/plow) and [Rubyforge](http://rubyforge.org/projects/plow/)
21
+
22
+ I'm currently working at towards assembling a "complete software" package for you. Please stay tuned for the official launch of version 1.0.0. :D
23
+
24
+ Please see {file:HISTORY} for the historical overview of the project.
25
+
26
+ SYNOPSIS
27
+ --------
28
+
29
+ Plows the fertile soil of your filesystem into neatly organized plots of web-site templates
30
+
31
+ FEATURES
32
+ --------
33
+
34
+ 1. Sharpens it's blade by ensuring that both a Linux system user account and it's home path exist
35
+ 2. Penetrates the soil by forming the web-site root path within the user home
36
+ 3. Seeds the web-site with an index page and web server log files
37
+ 4. Fertilizes the web-site by installing a virtual host configuration into the web server
38
+
39
+ REQUIREMENTS
40
+ ------------
41
+
42
+ **Supported operating system + web server combinations**
43
+
44
+ * Linux Ubuntu 8.04.3 LTS (Hardy Heron) + Apache 2.2.8
45
+
46
+ **Required dependencies**
47
+
48
+ * Ruby 1.9.1
49
+
50
+ **Optional automated specification dependencies**
51
+
52
+ * RSpec 1.2.8
53
+
54
+ **Optional generated API documentation dependencies**
55
+
56
+ * YARD 0.2.3.5
57
+ * BlueCloth 2.0.5
58
+
59
+ INSTALLING
60
+ ----------
61
+
62
+ Plow is distributed though the RubyGems ecosystem. Assuming you've already installed RubyGems, installing Plow is simple:
63
+
64
+ sudo gem install plow
65
+
66
+ LET ME BE CRYSTAL CLEAR. DO NOT INSTALL THIS PACKAGE TO ANY NON-ROOT USER'S GEM REPOSITORY. YOU'VE BEEN WARNED. Please see {file:SECURITY} for a detailed explanation of this advisory.
67
+
68
+ Note that Plow is RubyGems **compatible** while also simultaneously **decoupled** from it. Feel free to install Plow manually or use any Ruby package management system of your choice.
69
+
70
+ USAGE
71
+ -----
72
+
73
+ Usage: plow USER_NAME SITE_NAME [SITE_ALIAS ...]
74
+
75
+ Arguments:
76
+ USER_NAME Name of a Linux system account user (e.g. steve)
77
+ SITE_NAME Name of the web-site (e.g. www.apple.com)
78
+ SITE_ALIAS (Optional) List of alias names of the web-site (e.g. apple.com)
79
+
80
+ Plow is bundled with two executables named `plow` and `plow1.9`. They are nearly identical, but with the following exception:
81
+
82
+ * `plow` executes using the shell environment's `ruby` binary. (e.g. `#!/usr/bin/env ruby`)
83
+ * `plow1.9` executes using the shell environment's `ruby1.9` binary. (e.g. `#!/usr/bin/env ruby1.9`)
84
+
85
+ **Note:** If your Ruby 1.9 binary is something other than `ruby1.9` (i.e. like `ruby19`) then you'll need to create a shell alias similar to the following:
86
+
87
+ alias ruby1.9="`which ruby19`"
88
+
89
+ EXAMPLE
90
+ -------
91
+
92
+ $ plow steve www.apple.com apple.com
93
+
94
+ ... plow interation ...
95
+
96
+ $ tree /home/steve/sites/
97
+ /home/steve/sites/
98
+ |-- README
99
+ `-- www.apple.com
100
+ |-- log
101
+ | `-- apache2
102
+ | |-- access.log
103
+ | `-- error.log
104
+ `-- public
105
+ `-- index.html
106
+
107
+ 4 directories, 4 files
108
+
109
+ $ ls -hal /home/steve/sites/www.apple.com/log/apache2/
110
+ total 196K
111
+ drwxr-x--- 2 root steve 4.0K Sep 5 03:11 .
112
+ drwxr-xr-x 3 steve steve 4.0K Sep 5 03:09 ..
113
+ -rw-r----- 1 root steve 136K Sep 9 11:10 access.log
114
+ -rw-r----- 1 root steve 48K Sep 9 09:06 error.log
115
+
116
+ MOTIVATION
117
+ ----------
118
+
119
+ There exists numerous software products for controlling and/or managing a unix-based operating systems and web servers. So, why did I decide to write yet another? With Plow, I needed to prove to myself that I have the necessary proficiency **to contribute free, open-source, and complete software for the benefit human-kind**.
120
+
121
+ The terms "free" and "open-source" are common enough to be implicitly understood, or at least, [easily googled](http://www.google.com/searchq=free+open-source). But what of the term "complete software"? For me, complete software means four exclusive characteristics:
122
+
123
+ * Usability enhanced through elegant user-interface combined with straight-forward documentation
124
+ * Stability verified through automated test specifications
125
+ * Performance demonstrated through benchmarks
126
+ * Sustainability preserved through both human and computer readable code
127
+
128
+ I have tirelessly worked to achieve a high standard in all four characteristics. As my peer, I am grateful of your input on improving this project in any of these areas. Please see the sections on REPORTING ISSUES and CONTRIBUTING for further information.
129
+
130
+ REPORTING ISSUES
131
+ ----------------
132
+
133
+ Is Plow not behaving like you expect it should? Please forgive me! Would you take a moment to shed light on my negligence over at the [Issue Tracker](http://github.com/ryansobol/plow/issues)?
134
+
135
+ Thank you, in advance, for taking the time to help improve Plow.
136
+
137
+ CONTRIBUTING
138
+ ------------
139
+
140
+ Is Plow not behaving like you need? Open-source to the rescue! There is a plethora of documentation to bring you up to speed. The API documentation is generated, once the dependencies are met (please see the REQUIREMENTS section), by running the follow:
141
+
142
+ $ rake yardoc
143
+
144
+ Patches are always welcome and appreciated! To contribute your work back to the source, the process is straight-forward:
145
+
146
+ * Fork the project -- may I suggest [Github](http://www.github.com)?
147
+ * Make your feature addition or bug fix with specifications -- it's important that I don't break your hard work in a future version unintentionally.
148
+ * Please do not casually alter files in the project root. (e.g. HISTORY, LICENSE, Rakefile, README.markdown, ROAD-MAP, SECURITY, VERSION, etc.)
149
+ * Commit your changes and publish the change-set.
150
+ * Send me a pull request. All specs must pass!
151
+
152
+ Take a moment to get a feel for the style of coding, specifications, and in-line documentation. I apologize in advance for setting the standards so high. Please see {file:ROAD-MAP} to learn how to flow with the project.
data/ROAD-MAP ADDED
@@ -0,0 +1,10 @@
1
+ == Improvements
2
+
3
+ The obvious potential improvements are ported the package to additional operating systems and web servers. This would require minimal, but completely worth-while structure changes Plow::Generator class.
4
+
5
+ * Move all system administrative logic to model classes and redesign the class around the builder pattern to allow to construct user-determined classes dynamically at run-time
6
+ * Move all data validations to the same model classes or to new classes entirely, depending on the needs at the time
7
+ * More specific data validations
8
+ * Handing of more complex web application structures
9
+ * automatic deployment of web applications from github
10
+ * better argument parsing and including option flags as needed
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "plow"
8
+ gem.rubyforge_project = "plow"
9
+ gem.summary = "Plows the fertile soil of your filesystem into neatly organized plots of web-site templates"
10
+ gem.description = "Plows the fertile soil of your filesystem into neatly organized plots of web-site templates"
11
+ gem.email = "code@ryansobol.com"
12
+ gem.homepage = "http://github.com/ryansobol/plow"
13
+ gem.authors = ["Ryan Sobol"]
14
+ gem.add_development_dependency "rspec", "= 1.2.8"
15
+ gem.add_development_dependency "yard", "= 0.2.3.5"
16
+ gem.add_development_dependency "bluecloth", "= 2.0.5" # hidden yard dependency for markdown support
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+
21
+ Jeweler::RubyforgeTasks.new do |task|
22
+ task.doc_task = "yardoc"
23
+ end
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |task|
30
+ task.libs << 'lib' << 'spec'
31
+ task.spec_files = FileList['spec/**/*_spec.rb']
32
+ task.spec_opts = %w{ -O spec/spec.opts }
33
+ end
34
+
35
+ Spec::Rake::SpecTask.new(:rcov) do |task|
36
+ task.libs << 'lib' << 'spec'
37
+ task.pattern = 'spec/**/*_spec.rb'
38
+ task.rcov = true
39
+ end
40
+
41
+ task :spec => :check_dependencies
42
+
43
+ task :default => :spec
44
+
45
+ begin
46
+ require 'yard'
47
+ YARD::Rake::YardocTask.new
48
+ rescue LoadError => e
49
+ task :yardoc do
50
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
51
+ end
52
+ end
data/SECURITY ADDED
@@ -0,0 +1,14 @@
1
+ == A Brief Note About Security
2
+
3
+ Any and all processes invoking this library must be owned, aka executed, by the root user. Root ownership is required by this package to automate system administrative tasks, including but not limited to:
4
+
5
+ * Creating and/or modifying operating system user accounts that are _typically controlled by the root user_
6
+ * Generating and installing virtual host configuration files for web servers that are _typically owned by the root user_
7
+
8
+ By installing this package, you are acknowledging the risks inherit of the above implications. If this package, including the library source code and it's non-compiled executables, is owned by any non-root user, then anyone who has or gains access to that non-root account could modify the code in this package, without your knowledge. The next time you execute the program, as the root user, you could now be unwittingly comprising your own system by running malicious code injected into this package.
9
+
10
+ If you wish to install this package as a RubyGem with a user account granted root privileges via sudo, then please install this package by running the following command:
11
+
12
+ sudo gem install plow
13
+
14
+ LET ME BE CRYSTAL CLEAR. DO NOT INSTALL THIS PACKAGE TO ANY NON-ROOT USER'S GEM REPOSITORY. YOU'VE BEEN WARNED.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/plow ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__) + '/../lib'))
5
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
6
+ end
7
+
8
+ require 'plow'
9
+
10
+ Plow::Application.launch(*ARGV)
data/bin/plow1.9 ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby1.9
2
+ # encoding: UTF-8
3
+
4
+ unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__) + '/../lib'))
5
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
6
+ end
7
+
8
+ require 'plow'
9
+
10
+ Plow::Application.launch(*ARGV)
@@ -0,0 +1,66 @@
1
+ # encoding: UTF-8
2
+ require 'plow/generator'
3
+
4
+ class Plow
5
+ class Application
6
+ class << self
7
+ def launch(*arguments)
8
+ puts version_stamp
9
+
10
+ if arguments.length < 2
11
+ abort <<-MESSAGE
12
+ Usage: plow USER_NAME SITE_NAME [SITE_ALIAS ...]
13
+
14
+ Arguments:
15
+ USER_NAME Name of a Linux system account user (e.g. steve)
16
+ SITE_NAME Name of the web-site (e.g. www.apple.com)
17
+ SITE_ALIAS (Optional) List of alias names of the web-site (e.g. apple.com)
18
+
19
+ Summary:
20
+ Plows the fertile soil of your filesystem into neatly organized plots of web-site templates
21
+
22
+ Description:
23
+ 1. Sharpens it's blade by ensuring that both a Linux system user account and it's home path exist
24
+ 2. Penetrates the soil by forming the web-site root path within the user home
25
+ 3. Seeds the web-site with an index page and web server log files
26
+ 4. Fertilizes the web-site by installing a virtual host configuration into the web server
27
+
28
+ Example:
29
+ plow steve www.apple.com apple.com
30
+ MESSAGE
31
+ end
32
+
33
+ user_name, site_name = arguments.first(2)
34
+ site_aliases = arguments.drop(2)
35
+
36
+ begin
37
+ generator = Plow::Generator.new(user_name, site_name, *site_aliases)
38
+ generator.run!
39
+ return 0
40
+ rescue Plow::InvalidSystemUserNameError => invalid
41
+ abort "ERROR: #{invalid} is an invalid system user name"
42
+ rescue Plow::InvalidWebSiteNameError => invalid
43
+ abort "ERROR: #{invalid} is an invalid web-site name"
44
+ rescue Plow::InvalidWebSiteAliasError => invalid
45
+ abort "ERROR: #{invalid} is an invalid web-site alias"
46
+ rescue Plow::NonRootProcessOwnerError
47
+ abort "ERROR: This process must be owned or executed by root"
48
+ rescue Plow::ReservedSystemUserNameError => reserved
49
+ abort "ERROR: #{reserved} is a reserved system user name"
50
+ rescue Plow::SystemUserNameNotFoundError => not_found
51
+ abort "ERROR: System user name #{not_found} cannot be found when it should exist"
52
+ rescue Plow::AppRootAlreadyExistsError => already_exists
53
+ abort "ERROR: Application root path #{already_exists} already exists"
54
+ rescue Plow::ConfigFileAlreadyExistsError => already_exists
55
+ abort "ERROR: Configuration file #{already_exists} already exists"
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def version_stamp
62
+ "Plow v#{Plow::VERSION}. Copyright (c) 2009 Ryan Sobol. Licensed under the MIT license."
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+
3
+ class Plow
4
+ class BindingStruct
5
+ def initialize(hash)
6
+ hash.each_pair do |name, val|
7
+ instance_variable_set("@#{name}".to_sym, val)
8
+ end
9
+ end
10
+
11
+ def get_binding
12
+ binding
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+
3
+ class Object
4
+ # See http://api.rubyonrails.org/classes/Object.html#M000279
5
+ def blank?
6
+ respond_to?(:empty?) ? empty? : !self
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ class Plow
4
+ class NonRootProcessOwnerError < StandardError
5
+ end
6
+
7
+ class InvalidSystemUserNameError < StandardError
8
+ end
9
+
10
+ class InvalidWebSiteNameError < StandardError
11
+ end
12
+
13
+ class InvalidWebSiteAliasError < StandardError
14
+ end
15
+
16
+ class ReservedSystemUserNameError < StandardError
17
+ end
18
+
19
+ class SystemUserNameNotFoundError < StandardError
20
+ end
21
+
22
+ class AppRootAlreadyExistsError < StandardError
23
+ end
24
+
25
+ class ConfigFileAlreadyExistsError < StandardError
26
+ end
27
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'erb'
4
+
5
+ require 'plow/binding_struct'
6
+ require 'plow/strategy/ubuntu_hardy/user_home_web_app'
7
+
8
+ class Plow
9
+ class Generator
10
+ attr_reader :user_name, :site_name, :site_aliases
11
+ attr_reader :strategy
12
+
13
+ def initialize(user_name, site_name, *site_aliases)
14
+ if user_name.blank? || user_name.include?(' ')
15
+ raise(Plow::InvalidSystemUserNameError, user_name)
16
+ end
17
+
18
+ if site_name.blank? || site_name.include?(' ')
19
+ raise(Plow::InvalidWebSiteNameError, site_name)
20
+ end
21
+
22
+ site_aliases.each do |site_alias|
23
+ if site_alias.blank? || site_alias.include?(' ')
24
+ raise(Plow::InvalidWebSiteAliasError, site_alias)
25
+ end
26
+ end
27
+
28
+ @user_name = user_name
29
+ @site_name = site_name
30
+ @site_aliases = site_aliases
31
+
32
+ @strategy = Plow::Strategy::UbuntuHardy::UserHomeWebApp.new(self)
33
+ end
34
+
35
+ def run!
36
+ raise Plow::NonRootProcessOwnerError unless Process.uid == 0
37
+ strategy.execute
38
+ end
39
+
40
+ def say(message)
41
+ puts "==> #{message}"
42
+ end
43
+
44
+ def shell(commands)
45
+ commands.each_line do |command|
46
+ command.strip!
47
+ system(command) unless command.blank?
48
+ end
49
+ end
50
+
51
+ def evaluate_template(template_path, context)
52
+ template = File.read(template_path)
53
+ context_struct = Plow::BindingStruct.new(context)
54
+ ERB.new(template).result(context_struct.get_binding)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,19 @@
1
+ $ tree sites/
2
+ sites/
3
+ |-- README
4
+ `-- example.ryansobol.com
5
+ |-- log
6
+ | `-- apache2
7
+ | |-- access.log
8
+ | `-- error.log
9
+ `-- public
10
+ `-- index.html
11
+
12
+ 4 directories, 4 files
13
+
14
+ $ ls -hal sites/example.ryansobol.com/log/apache2/
15
+ total 196K
16
+ drwxr-x--- 2 root GROUP 4.0K Sep 5 03:11 .
17
+ drwxr-xr-x 3 USER GROUP 4.0K Sep 5 03:09 ..
18
+ -rw-r----- 1 root GROUP 136K Sep 9 11:10 access.log
19
+ -rw-r----- 1 root GROUP 48K Sep 9 09:06 error.log
@@ -0,0 +1,14 @@
1
+ <%# encoding: UTF-8 %>
2
+ <VirtualHost *:80>
3
+ ServerAdmin webmaster
4
+ ServerName <%= @site_name %>
5
+ <% for site_alias in @site_aliases %>
6
+ ServerAlias <%= site_alias %>
7
+ <% end %>
8
+ DirectoryIndex index.html
9
+ DocumentRoot <%= @app_public_path %>
10
+
11
+ LogLevel warn
12
+ ErrorLog <%= @app_log_path %>/apache2/error.log
13
+ CustomLog <%= @app_log_path %>/apache2/access.log combined
14
+ </VirtualHost>