Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

amazon-ssm-agent: Add dynamically-linked agent binaries #22

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
From c835d2ddc855439173a8a59828c335d169c03d15 Mon Sep 17 00:00:00 2001
From: Kush Upadhyay <[email protected]>
Date: Tue, 2 Jul 2024 20:54:29 +0000
Subject: [PATCH] agent: Add config to make shell optional

Signed-off-by: Kush Upadhyay <[email protected]>
---
agent/appconfig/appconfig.go | 1 +
agent/appconfig/contracts.go | 2 ++
agent/plugins/runscript/runscript.go | 36 +++++++++++++++++++---------
3 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/agent/appconfig/appconfig.go b/agent/appconfig/appconfig.go
index b6abcf1..e214cd5 100644
--- a/agent/appconfig/appconfig.go
+++ b/agent/appconfig/appconfig.go
@@ -118,6 +118,7 @@ func DefaultConfig() SsmagentConfig {
SessionLogsRetentionDurationHours: DefaultSessionLogsRetentionDurationHours,
PluginLocalOutputCleanup: DefaultPluginOutputRetention,
OrchestrationDirectoryCleanup: DefaultOrchestrationDirCleanup,
+ UseShell: false,
koooosh marked this conversation as resolved.
Show resolved Hide resolved
}
var agent = AgentInfo{
Name: "amazon-ssm-agent",
diff --git a/agent/appconfig/contracts.go b/agent/appconfig/contracts.go
index 1337398..0a66441 100644
--- a/agent/appconfig/contracts.go
+++ b/agent/appconfig/contracts.go
@@ -50,6 +50,8 @@ type SsmCfg struct {
PluginLocalOutputCleanup string
// Configure only when it is safe to delete orchestration folder after document execution. This config overrides PluginLocalOutputCleanup when set.
OrchestrationDirectoryCleanup string
+ // Flag for shell dependency
+ UseShell bool
}

// AgentInfo represents metadata for amazon-ssm-agent
diff --git a/agent/plugins/runscript/runscript.go b/agent/plugins/runscript/runscript.go
index 48be5e7..d8cbcf1 100644
--- a/agent/plugins/runscript/runscript.go
+++ b/agent/plugins/runscript/runscript.go
@@ -174,23 +174,37 @@ func (p *Plugin) runCommands(pluginID string, pluginInput RunScriptPluginInput,
return
}

- // Create script file path
- scriptPath := filepath.Join(orchestrationDir, p.ScriptName)
- log.Debugf("Writing commands %v to file %v", pluginInput, scriptPath)
+ appConfig := p.Context.AppConfig()

- // Create script file
- if err = pluginutil.CreateScriptFile(log, scriptPath, pluginInput.RunCommand, p.ByteOrderMark); err != nil {
- output.MarkAsFailed(fmt.Errorf("failed to create script file. %v", err))
- return
+ var commandName string
+ var commandArguments []string
+
+ if appConfig.Ssm.UseShell {
+
+ // Create script file path
+ scriptPath := filepath.Join(orchestrationDir, p.ScriptName)
+ log.Debugf("Writing commands %v to file %v", pluginInput, scriptPath)
+
+ // Create script file
+ if err = pluginutil.CreateScriptFile(log, scriptPath, pluginInput.RunCommand, p.ByteOrderMark); err != nil {
+ output.MarkAsFailed(fmt.Errorf("failed to create script file. %v", err))
+ return
+ }
+
+ // Construct Command Name and Arguments
+ commandName = p.ShellCommand
+ commandArguments = append(p.ShellArguments, scriptPath)
+ } else {
+
+ // Take only the first element of RunCommand since we prefer single-line commands
+ commandInput := strings.Split(pluginInput.RunCommand[0], " ")
koooosh marked this conversation as resolved.
Show resolved Hide resolved
+ commandName = commandInput[0]
+ commandArguments = append(commandInput[1:])
}

// Set execution time
executionTimeout := pluginutil.ValidateExecutionTimeout(log, pluginInput.TimeoutSeconds)

- // Construct Command Name and Arguments
- commandName := p.ShellCommand
- commandArguments := append(p.ShellArguments, scriptPath)
-
// Execute Command
exitCode, err := p.CommandExecuter.NewExecute(p.Context, workingDir, output.GetStdoutWriter(), output.GetStderrWriter(), cancelFlag, executionTimeout, commandName, commandArguments, pluginInput.Environment)

--
2.40.1

62 changes: 62 additions & 0 deletions packages/amazon-ssm-agent/amazon-ssm-agent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"Profile":{
"ShareCreds" : true,
"ShareProfile" : "",
"ForceUpdateCreds" : false,
"KeyAutoRotateDays": 0
},
"Mds": {
"CommandWorkersLimit" : 5,
"StopTimeoutMillis" : 20000,
"Endpoint": "",
"CommandRetryLimit": 15
},
"Ssm": {
"Endpoint": "",
"HealthFrequencyMinutes": 5,
"CustomInventoryDefaultLocation" : "",
"AssociationLogsRetentionDurationHours" : 24,
"RunCommandLogsRetentionDurationHours" : 336,
"SessionLogsRetentionDurationHours" : 336,
"PluginLocalOutputCleanup": "",
"OrchestrationDirectoryCleanup": "",
"UseShell": false
},
"Mgs": {
"Region": "",
"Endpoint": "",
"StopTimeoutMillis" : 20000,
"SessionWorkersLimit" : 1000,
"DeniedPortForwardingRemoteIPs" : [
"169.254.169.254",
"fd00:ec2::254",
"169.254.169.253",
"fd00:ec2::253",
"169.254.169.123",
"169.254.169.250"
]
},
"Agent": {
"Region": "",
"OrchestrationRootDir": "",
"SelfUpdate": false,
"TelemetryMetricsToCloudWatch": false,
"TelemetryMetricsToSSM": true,
"AuditExpirationDay" : 7,
"LongRunningWorkerMonitorIntervalSeconds": 60
},
"Os": {
"Lang": "en-US",
"Name": "",
"Version": "1"
},
"S3": {
"Endpoint": "",
"Region": "",
"LogBucket":"",
"LogKey":""
},
"Kms": {
"Endpoint": ""
}
}
18 changes: 18 additions & 0 deletions packages/amazon-ssm-agent/amazon-ssm-agent.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[Unit]
Description=Amazon SSM agent

[Service]
Type=simple
ExecStart=/usr/bin/amazon-ssm-agent
KillMode=process

# Restart the agent regardless of whether it crashes (and returns a non-zero result code) or if
# is terminated normally (e.g. via 'kill -HUP'). Delay restart so that the agent is less likely
# to restart during a reboot initiated by a script. If the agent exits with status 194 (reboot
# requested), don't restart at all.
Restart=always
RestartPreventExitStatus=194
RestartSec=5

[Install]
WantedBy=multi-user.target
87 changes: 81 additions & 6 deletions packages/amazon-ssm-agent/amazon-ssm-agent.spec
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ Summary: An agent to enable remote management of EC2 instances
License: Apache-2.0
URL: https://github.com/aws/amazon-ssm-agent
Source0: %{gorepo}-%{version}.tar.gz
Source1: amazon-ssm-agent.service
Source2: amazon-ssm-agent.json
Source1000: clarify.toml

Patch0001: 0001-agent-Add-config-to-make-shell-optional.patch

BuildRequires: %{_cross_os}glibc-devel
Requires: %{name}(binaries)

Expand All @@ -35,11 +39,36 @@ Conflicts: (%{_cross_os}image-feature(no-fips) or %{name}-bin)
%description fips-bin
%{summary}.

%package plugin
Summary: A statically-linked agent to enable remote management of EC2 instances
Requires: %{name}-plugin(binaries)

%description plugin
%{summary}.

%package plugin-bin
Summary: Statically-linked remote management agent binaries
Provides: %{name}-plugin(binaries)
Requires: (%{_cross_os}image-feature(no-fips) and %{name}-plugin)
Conflicts: (%{_cross_os}image-feature(fips) or %{name}-plugin-fips-bin)

%description plugin-bin
%{summary}.

%package plugin-fips-bin
Summary: Statically-linked remote management agent binaries, FIPS edition
Provides: %{name}-plugin(binaries)
Requires: (%{_cross_os}image-feature(fips) and %{name}-plugin)
Conflicts: (%{_cross_os}image-feature(no-fips) or %{name}-plugin-bin)

%description plugin-fips-bin
%{summary}.

%prep
%setup -n %{gorepo}-%{version}
%autosetup -n %{gorepo}-%{version} -p0001

%build
%set_cross_go_flags_static
%set_cross_go_flags

go build -ldflags "${GOLDFLAGS}" -o amazon-ssm-agent \
./core/agent.go ./core/agent_unix.go ./core/agent_parser.go
Expand All @@ -59,12 +88,43 @@ go build -ldflags "${GOLDFLAGS}" -o ssm-session-worker \
gofips build -ldflags "${GOLDFLAGS}" -o fips/ssm-session-worker \
./agent/framework/processor/executer/outofproc/sessionworker/main.go

%set_cross_go_flags_static

go build -ldflags "${GOLDFLAGS}" -o static/amazon-ssm-agent \
./core/agent.go ./core/agent_unix.go ./core/agent_parser.go

gofips build -ldflags "${GOLDFLAGS}" -o fips-static/amazon-ssm-agent \
./core/agent.go ./core/agent_unix.go ./core/agent_parser.go

go build -ldflags "${GOLDFLAGS}" -o static/ssm-agent-worker \
./agent/agent.go ./agent/agent_unix.go ./agent/agent_parser.go

gofips build -ldflags "${GOLDFLAGS}" -o fips-static/ssm-agent-worker \
./agent/agent.go ./agent/agent_unix.go ./agent/agent_parser.go

go build -ldflags "${GOLDFLAGS}" -o static/ssm-session-worker \
./agent/framework/processor/executer/outofproc/sessionworker/main.go

gofips build -ldflags "${GOLDFLAGS}" -o fips-static/ssm-session-worker \
./agent/framework/processor/executer/outofproc/sessionworker/main.go

%install
# Install the SSM agent under 'libexecdir', since it is meant to be used by other programs
install -D -p -m 0644 %{S:1} %{buildroot}%{_cross_unitdir}/amazon-ssm-agent.service

install -d %{buildroot}%{_cross_factorydir}%{_cross_sysconfdir}/amazon/ssm
install -m 0644 %{S:2} %{buildroot}%{_cross_factorydir}%{_cross_sysconfdir}/amazon/ssm/amazon-ssm-agent.json

install -d %{buildroot}{%{_cross_bindir},%{_cross_fips_bindir}}
for b in amazon-ssm-agent ssm-agent-worker ssm-session-worker; do
install -p -m 0755 ${b} %{buildroot}%{_cross_bindir}
install -p -m 0755 fips/${b} %{buildroot}%{_cross_fips_bindir}
done

# Install the statically-linked SSM agent under 'libexecdir', since it is meant to be used by other programs
install -d %{buildroot}{%{_cross_libexecdir},%{_cross_fips_libexecdir}}/amazon-ssm-agent/bin/%{version}
for b in amazon-ssm-agent ssm-agent-worker ssm-session-worker; do
install -p -m 0755 ${b} %{buildroot}%{_cross_libexecdir}/amazon-ssm-agent/bin/%{version}
install -p -m 0755 fips/${b} %{buildroot}%{_cross_fips_libexecdir}/amazon-ssm-agent/bin/%{version}
install -p -m 0755 static/${b} %{buildroot}%{_cross_libexecdir}/amazon-ssm-agent/bin/%{version}
install -p -m 0755 fips-static/${b} %{buildroot}%{_cross_fips_libexecdir}/amazon-ssm-agent/bin/%{version}
done

%cross_scan_attribution --clarify %{S:1000} go-vendor vendor
Expand All @@ -76,15 +136,30 @@ ln -sf %{version} %{buildroot}%{_cross_fips_libexecdir}/amazon-ssm-agent/bin/lat
%license LICENSE
%{_cross_attribution_file}
%{_cross_attribution_vendor_dir}
%{_cross_unitdir}/amazon-ssm-agent.service
%dir %{_cross_factorydir}%{_cross_sysconfdir}/amazon/ssm
%{_cross_factorydir}%{_cross_sysconfdir}/amazon/ssm/amazon-ssm-agent.json

%files bin
%{_cross_bindir}/amazon-ssm-agent
%{_cross_bindir}/ssm-agent-worker
%{_cross_bindir}/ssm-session-worker

%files fips-bin
%{_cross_fips_bindir}/amazon-ssm-agent
%{_cross_fips_bindir}/ssm-agent-worker
%{_cross_fips_bindir}/ssm-session-worker

%files plugin

%files plugin-bin
%dir %{_cross_libexecdir}/amazon-ssm-agent
%{_cross_libexecdir}/amazon-ssm-agent/bin/%{version}/amazon-ssm-agent
%{_cross_libexecdir}/amazon-ssm-agent/bin/%{version}/ssm-agent-worker
%{_cross_libexecdir}/amazon-ssm-agent/bin/%{version}/ssm-session-worker
%{_cross_libexecdir}/amazon-ssm-agent/bin/latest

%files fips-bin
%files plugin-fips-bin
%dir %{_cross_fips_libexecdir}/amazon-ssm-agent
%{_cross_fips_libexecdir}/amazon-ssm-agent/bin/%{version}/amazon-ssm-agent
%{_cross_fips_libexecdir}/amazon-ssm-agent/bin/%{version}/ssm-agent-worker
Expand Down
2 changes: 1 addition & 1 deletion packages/ecs-agent/ecs-agent.spec
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ BuildRequires: %{_cross_os}glibc-devel

Requires: %{_cross_os}docker-engine
Requires: %{_cross_os}iptables
Requires: %{_cross_os}amazon-ssm-agent
Requires: %{_cross_os}amazon-ssm-agent-plugin
Requires: %{name}(binaries)

%description
Expand Down