-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathset-capistrano-permissions
executable file
·120 lines (103 loc) · 3.47 KB
/
set-capistrano-permissions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env ruby
require File.expand_path(File.dirname(__FILE__) + '/shared')
require 'optparse'
def parse_options
options = {}
parser = OptionParser.new do |opts|
nl = "\n" + ' ' * 37
opts.banner = "Usage: set-capistrano-permissions [options]"
opts.separator ""
opts.separator "Options:"
opts.on("--for-app-dir DIR",
"Set only permissions for the given app#{nl}" +
"directory") do |value|
options[:for_app_dir] = value
end
end
begin
parser.parse!
rescue OptionParser::ParseError => e
puts e
puts
puts "Please see '--help' for valid options."
exit 1
end
if options[:help]
puts parser
exit
else
return options
end
end
# Set the permissions on a /u/apps/.../releases/... directory.
def set_permissions_on_release_dir(dir)
# Deny web server access to everything except for a few things.
sh "deny #{WWW_USER} #{dir}"
# Executable access to the directory itself
# so that the web server can access subdirectories.
sh "setfacl -m user:#{WWW_USER}:--x #{dir}"
# Read-only access to the 'public' directory so that
# the web server can serve static assets.
if File.directory?("#{dir}/public")
sh "permit #{WWW_USER} #{dir}/public"
end
# Executable access to the 'config' directory so that
# Phusion Passenger's app autodetection works.
if File.directory?("#{dir}/config")
sh "setfacl -m user:#{WWW_USER}:--x #{dir}/config"
end
end
# Set the permissions on a /u/apps/... directory.
def set_permissions_on_app_dir(dir)
# Give the web server read-only access to everything.
# We tighten up permissions in later commands.
sh "permit #{WWW_USER} #{dir}"
# Make the application directory itself executable-only
# by the web server.
if File.directory?("#{dir}/releases") || File.directory?("#{dir}/shared")
sh "setfacl -m user:#{WWW_USER}:--x #{dir}"
sh "setfacl -d -m user:#{WWW_USER}:--x #{dir}"
end
# Make the 'releases' directory executable-only by the web server
# and set correct permissions on each release subdirectory.
if File.directory?("#{dir}/releases")
sh "setfacl -m user:#{WWW_USER}:--x #{dir}/releases"
Dir["#{dir}/releases/*"].each do |release_subdir|
set_permissions_on_release_dir(release_subdir)
end
end
# Deny web server access to everything in the 'shared'
# directory, with some exceptions.
if File.directory?("#{dir}/shared")
sh "deny #{WWW_USER} #{dir}/shared"
# If there's a Capistrano repository cache, then give
# it the same permissions as a release directory because
# Capistrano actually makes a release directory but copying
# cached-copy with 'cp -dpR', thereby copying all ACLs too.
if File.directory?("#{dir}/shared/cached-copy")
set_permissions_on_release_dir("#{dir}/shared/cached-copy")
end
# If you store attachment files in the 'shared'
# directory then you can allow read-only access to that:
# sh "setfacl -m user:#{WWW_USER}:--x #{dir}/shared"
# sh "permit #{dir}/shared/attachments"
end
end
def start
options = parse_options
if options[:for_app_dir]
sh "setfacl -m user:#{WWW_USER}:--x #{CAPISTRANO_DIR}"
sh "setfacl -d -m user:#{WWW_USER}:r-x #{CAPISTRANO_DIR}"
set_permissions_on_app_dir(options[:for_app_dir])
else
sh "chmod -R g+w,o-rwx #{CAPISTRANO_DIR}"
sh "setfacl -m user:#{WWW_USER}:--x #{CAPISTRANO_DIR}"
sh "setfacl -d -m user:#{WWW_USER}:r-x #{CAPISTRANO_DIR}"
Dir["#{CAPISTRANO_DIR}/*"].each do |dir|
set_permissions_on_app_dir(dir)
end
end
end
CAPISTRANO_DIR = config(:capistrano_dir)
WWW_USER = config(:www_user)
start