Skip to content

Commit 2a24130

Browse files
committed
Merge pull request #53 from ccloes-intuit/add_sudo_support
Add sudo support
2 parents 5c4fe53 + bd38c04 commit 2a24130

File tree

7 files changed

+97
-14
lines changed

7 files changed

+97
-14
lines changed

init.d/codedeploy-agent

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,53 @@ RETVAL=0
2222
[ -f /etc/profile ] && [ "`stat --format '%U %G' /etc/profile`" == "root root" ] && source /etc/profile
2323

2424
prog="codedeploy-agent"
25+
# Modify the following USER variable to run the codedeploy process as a non-root user
26+
# Note: You also need to chown /opt/codedeploy /var/log/aws
27+
USER=""
2528
AGENT_ROOT="/opt/codedeploy-agent/"
2629
INSTALLER="/opt/codedeploy-agent/bin/install"
2730
BIN="/opt/codedeploy-agent/bin/codedeploy-agent"
2831

2932
start() {
3033
echo -n $"Starting $prog:"
3134
cd $AGENT_ROOT
32-
nohup $BIN start >/dev/null </dev/null 2>&1 # Try to start the server
35+
if [ $USER ]; then
36+
nohup sudo -i -u $USER $BIN start >/dev/null </dev/null 2>&1 # Try to start the server
37+
else
38+
nohup $BIN start >/dev/null </dev/null 2>&1 # Try to start the server
39+
fi
3340
exit $?
3441
}
3542

3643
stop() {
3744
echo -n $"Stopping $prog:"
3845
cd $AGENT_ROOT
39-
nohup $BIN stop >/dev/null </dev/null 2>&1 # Try to stop the server
46+
if [ $USER ]; then
47+
nohup sudo -i -u $USER $BIN stop >/dev/null </dev/null 2>&1 # Try to stop the server
48+
else
49+
nohup $BIN stop >/dev/null </dev/null 2>&1 # Try to stop the server
50+
fi
4051
exit $?
4152
}
4253

4354
restart() {
4455
echo -n $"Restarting $prog:"
4556
cd $AGENT_ROOT
46-
nohup $BIN restart >/dev/null </dev/null 2>&1 # Try to restart the server
57+
if [ $USER ]; then
58+
nohup sudo -i -u $USER $BIN restart >/dev/null </dev/null 2>&1 # Try to restart the server
59+
else
60+
nohup $BIN restart >/dev/null </dev/null 2>&1 # Try to restart the server
61+
fi
4762
exit $?
4863
}
4964

5065
status() {
5166
cd $AGENT_ROOT
52-
$BIN status # Status of the server
67+
if [ $USER ]; then
68+
sudo -i -u $USER $BIN status # Status of the server
69+
else
70+
$BIN status # Status of the server
71+
fi
5372
exit $?
5473
}
5574

init.d/codedeploy-agent.service

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[Unit]
2+
Description=AWS CodeDeploy Host Agent
3+
4+
[Service]
5+
Type=forking
6+
ExecStart=/opt/codedeploy-agent/bin/codedeploy-agent start
7+
ExecStop=/opt/codedeploy-agent/bin/codedeploy-agent stop
8+
RemainAfterExit=no
9+
# Comment out the following line to run the agent as the codedeploy user
10+
# Note: The user must first exist on the system
11+
#User=codedeploy
12+
13+
[Install]
14+
WantedBy=multi-user.target

lib/instance_agent/platform/linux_util.rb

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,27 @@ def self.supported_oses()
88
['linux']
99
end
1010

11-
def self.prepare_script_command(script, absolute_path)
12-
script_command = absolute_path
13-
if(!script.runas.nil?)
14-
script_command = 'su ' + script.runas + ' -c ' + absolute_path
11+
def self.prepare_script_command(script, absolute_cmd_path)
12+
runas = !!script.runas
13+
sudo = !!script.sudo
14+
15+
if runas && sudo
16+
return 'sudo su ' + script.runas + ' -c ' + absolute_cmd_path
17+
end
18+
19+
if runas && !sudo
20+
return 'su ' + script.runas + ' -c ' + absolute_cmd_path
21+
end
22+
23+
if !runas && sudo
24+
return 'sudo ' + absolute_cmd_path
1525
end
16-
script_command
26+
27+
# If neither sudo or runas is specified, execute the
28+
# command as the code deploy agent user
29+
absolute_cmd_path
1730
end
18-
31+
1932
def self.quit()
2033
# Send kill signal to parent and exit
2134
Process.kill('TERM', Process.ppid)
@@ -46,6 +59,7 @@ def self.codedeploy_version_file
4659
def self.fallback_version_file
4760
"/opt/codedeploy-agent"
4861
end
62+
4963
private
5064
def self.execute_tar_command(cmd)
5165
log(:debug, "Executing #{cmd}")

lib/instance_agent/plugins/codedeploy/application_specification/application_specification.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def parse_hooks(hooks_hash)
6060
current_hook_scripts << InstanceAgent::Plugins::CodeDeployPlugin::ApplicationSpecification::ScriptInfo.new(script['location'].to_s.strip,
6161
{
6262
:runas => script.has_key?('runas') && !script['runas'].nil? ? script['runas'].to_s.strip : nil,
63+
:sudo => script['sudo'],
6364
:timeout => script['timeout']
6465
})
6566
else
@@ -140,4 +141,4 @@ def parse_context(context)
140141
end
141142
end
142143
end
143-
end
144+
end

lib/instance_agent/plugins/codedeploy/application_specification/script_info.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ module ApplicationSpecification
55
#Helper Class for storing data parsed from hook script maps
66
class ScriptInfo
77

8-
attr_reader :location, :runas, :timeout
8+
attr_reader :location, :runas, :sudo, :timeout
99
def initialize(location, opts = {})
1010
location = location.to_s
1111
if(location.empty?)
1212
raise AppSpecValidationException, 'Scripts need a location value'
1313
end
1414
@location = location
1515
@runas = opts[:runas]
16+
@sudo = opts[:sudo]
1617
@timeout = opts[:timeout] || 3600
1718
@timeout = @timeout.to_i
1819
if(@timeout <= 0)
@@ -24,4 +25,4 @@ def initialize(location, opts = {})
2425
end
2526
end
2627
end
27-
end
28+
end

lib/instance_agent/plugins/codedeploy/command_executor.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ module InstanceAgent
1111
module Plugins
1212
module CodeDeployPlugin
1313
ARCHIVES_TO_RETAIN = 5
14-
1514
class CommandExecutor
1615
class << self
1716
attr_reader :command_methods
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require 'test_helper'
2+
3+
class LinuxUtilTest < InstanceAgentTestCase
4+
context 'Testing building command with sudo' do
5+
setup do
6+
@script_mock = Struct.new :sudo, :runas
7+
end
8+
9+
should 'return command with sudo with runas user deploy' do
10+
mock = @script_mock.new true, "deploy"
11+
assert_equal 'sudo su deploy -c my_script.sh',
12+
InstanceAgent::LinuxUtil.prepare_script_command(mock, "my_script.sh")
13+
end
14+
15+
should 'return command without sudo with runas user deploy' do
16+
mock = @script_mock.new nil, "deploy"
17+
assert_equal 'su deploy -c my_script.sh',
18+
InstanceAgent::LinuxUtil.prepare_script_command(mock, "my_script.sh")
19+
end
20+
21+
should 'return command without sudo or runas user' do
22+
mock = @script_mock.new nil, nil
23+
assert_equal 'my_script.sh',
24+
InstanceAgent::LinuxUtil.prepare_script_command(mock, "my_script.sh")
25+
end
26+
27+
should 'return command with sudo' do
28+
mock = @script_mock.new true, nil
29+
assert_equal 'sudo my_script.sh',
30+
InstanceAgent::LinuxUtil.prepare_script_command(mock, "my_script.sh")
31+
end
32+
33+
end
34+
end
35+

0 commit comments

Comments
 (0)