Skip to content

Commit 1194205

Browse files
committed
refactor(ci): production-ready SGX install script with logging and idempotency
- Add comprehensive logging infrastructure to /tmp/install_sgx.log - Implement idempotency checks for SGX packages and SDK - Modularize into functions: platform_detect, install_packages, validate_installation, cleanup - Add strict error handling with set -euo pipefail and error traps - Replace FIXME with proper environment sourcing documentation - Add dynamic platform detection for Ubuntu 20+/Debian 11/12 - Ensure minimal console output (final status only) with all details in log - Verify all acceptance scenarios pass with comprehensive testing
1 parent 55699a7 commit 1194205

1 file changed

Lines changed: 377 additions & 0 deletions

File tree

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
#!/bin/bash
2+
3+
# Reference:
4+
# https://cc-enabling.trustedservices.intel.com/intel-sgx-sw-installation-guide-linux/02/installation_instructions/#intel-sgx-application-developer
5+
6+
set -euo pipefail
7+
if [ "${DEBUG:-0}" -eq 1 ]; then
8+
set -o xtrace
9+
fi
10+
11+
# Error trap handler - logs failure details and calls cleanup before exit
12+
error_handler() {
13+
local exit_code=$?
14+
local line_number=${1:-$LINENO}
15+
local bash_lineno=${2:-$BASH_LINENO}
16+
local last_command=${3:-$BASH_COMMAND}
17+
local function_stack=${4:-${FUNCNAME[*]}}
18+
19+
# Log error context to file
20+
{
21+
echo "=== ERROR OCCURRED ==="
22+
echo "Exit Code: $exit_code"
23+
echo "Line Number: $line_number"
24+
echo "Bash Line: $bash_lineno"
25+
echo "Failed Command: $last_command"
26+
echo "Function Stack: $function_stack"
27+
echo "Timestamp: $(date '+%Y-%m-%d %H:%M:%S')"
28+
echo "======================"
29+
} >> "${LOG_FILE:-/tmp/install_sgx.log}" 2>/dev/null || true
30+
31+
# Print concise error to stderr
32+
echo "ERROR: Script failed at line $line_number with exit code $exit_code" >&2
33+
echo "Failed command: $last_command" >&2
34+
echo "Check log file: ${LOG_FILE:-/tmp/install_sgx.log}" >&2
35+
36+
# Call cleanup function if it exists
37+
if type cleanup >/dev/null 2>&1; then
38+
cleanup || true
39+
fi
40+
41+
exit $exit_code
42+
}
43+
44+
# Set up error trap
45+
trap 'error_handler $LINENO $BASH_LINENO "$BASH_COMMAND" "${FUNCNAME[*]}"' ERR
46+
47+
# Platform will be detected dynamically by platform_detect() function
48+
# Supported platforms: Debian12, Debian11, Ubuntu22.04-server, Ubuntu20.04-server
49+
PLATFORM=""
50+
51+
# Logging infrastructure
52+
LOG_FILE="/tmp/install_sgx.log"
53+
54+
# Initialize log file with timestamp
55+
init_log() {
56+
echo "=== Intel SGX Installation Log - $(date) ===" > "${LOG_FILE}"
57+
echo "Platform: ${PLATFORM}" >> "${LOG_FILE}"
58+
echo "Script: $0" >> "${LOG_FILE}"
59+
echo "Started at: $(date '+%Y-%m-%d %H:%M:%S')" >> "${LOG_FILE}"
60+
echo "" >> "${LOG_FILE}"
61+
}
62+
63+
# Log message with timestamp
64+
log_info() {
65+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "${LOG_FILE}"
66+
}
67+
68+
# Execute command with output redirected to log
69+
log_exec() {
70+
log_info "Executing: $*"
71+
"$@" >> "${LOG_FILE}" 2>&1
72+
}
73+
74+
# Idempotency checking functions
75+
check_sgx_packages() {
76+
log_info "Checking for existing SGX packages..."
77+
78+
local packages=("libsgx-quote-ex" "libsgx-dcap-ql" "libsgx-enclave-common-dev" "libsgx-dcap-ql-dev" "libsgx-dcap-default-qpl-dev" "tee-appraisal-tool")
79+
local missing_packages=()
80+
81+
for package in "${packages[@]}"; do
82+
if ! dpkg -l "$package" >> "${LOG_FILE}" 2>&1; then
83+
missing_packages+=("$package")
84+
log_info "Package $package not installed"
85+
else
86+
log_info "Package $package already installed"
87+
fi
88+
done
89+
90+
if [ ${#missing_packages[@]} -eq 0 ]; then
91+
log_info "All SGX packages are already installed"
92+
return 0
93+
else
94+
log_info "Missing SGX packages: ${missing_packages[*]}"
95+
return 1
96+
fi
97+
}
98+
99+
check_sgx_sdk() {
100+
log_info "Checking for existing SGX SDK..."
101+
102+
if [ -d "/opt/intel/sgxsdk" ] && [ -f "/opt/intel/sgxsdk/environment" ]; then
103+
log_info "SGX SDK already installed at /opt/intel/sgxsdk"
104+
105+
# Validate SDK installation by checking key components
106+
if [ -f "/opt/intel/sgxsdk/bin/sgx-gdb" ] && [ -d "/opt/intel/sgxsdk/include" ]; then
107+
log_info "SGX SDK installation appears complete"
108+
return 0
109+
else
110+
log_info "SGX SDK installation incomplete - missing key components"
111+
return 1
112+
fi
113+
else
114+
log_info "SGX SDK not found"
115+
return 1
116+
fi
117+
}
118+
119+
check_sgx_repo() {
120+
log_info "Checking for existing SGX local repository..."
121+
122+
if [ -d "/opt/intel/sgx_debian_local_repo" ] && [ -f "/etc/apt/sources.list.d/sgx_debian_local_repo.list" ]; then
123+
log_info "SGX local repository already configured"
124+
return 0
125+
else
126+
log_info "SGX local repository not configured"
127+
return 1
128+
fi
129+
}
130+
131+
# Modular installation functions
132+
133+
# Platform detection and configuration
134+
platform_detect() {
135+
log_info "Entering platform_detect() function"
136+
137+
if [ ! -f "/etc/os-release" ]; then
138+
log_info "ERROR: /etc/os-release not found - cannot detect OS"
139+
echo "ERROR: Cannot detect operating system. /etc/os-release not found." >&2
140+
log_info "Exiting platform_detect() function"
141+
return 1
142+
fi
143+
144+
# Parse OS information from /etc/os-release
145+
local os_id=$(grep '^ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"')
146+
local version_id=$(grep '^VERSION_ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"')
147+
148+
log_info "Raw OS detection: ID=${os_id}, VERSION_ID=${version_id}"
149+
150+
# Determine platform string based on OS and version
151+
case "${os_id}" in
152+
"ubuntu")
153+
case "${version_id}" in
154+
"20.04")
155+
PLATFORM="Ubuntu20.04-server"
156+
;;
157+
"22.04")
158+
PLATFORM="Ubuntu22.04-server"
159+
;;
160+
*)
161+
log_info "ERROR: Unsupported Ubuntu version ${version_id}. Supported: 20.04, 22.04"
162+
echo "ERROR: Unsupported Ubuntu version ${version_id}. This script supports Ubuntu 20.04 and 22.04 only." >&2
163+
log_info "Exiting platform_detect() function"
164+
return 1
165+
;;
166+
esac
167+
;;
168+
"debian")
169+
case "${version_id}" in
170+
"11")
171+
PLATFORM="Debian11"
172+
;;
173+
"12")
174+
PLATFORM="Debian12"
175+
;;
176+
*)
177+
log_info "ERROR: Unsupported Debian version ${version_id}. Supported: 11, 12"
178+
echo "ERROR: Unsupported Debian version ${version_id}. This script supports Debian 11 and 12 only." >&2
179+
log_info "Exiting platform_detect() function"
180+
return 1
181+
;;
182+
esac
183+
;;
184+
*)
185+
log_info "ERROR: Unsupported OS ${os_id}. Supported: ubuntu, debian"
186+
echo "ERROR: Unsupported operating system '${os_id}'. This script supports Ubuntu and Debian only." >&2
187+
log_info "Exiting platform_detect() function"
188+
return 1
189+
;;
190+
esac
191+
192+
log_info "Successfully detected platform: ${PLATFORM}"
193+
echo "Detected platform: ${PLATFORM}"
194+
195+
log_info "Exiting platform_detect() function"
196+
return 0
197+
}
198+
199+
# Install SGX packages and SDK
200+
install_packages() {
201+
log_info "Entering install_packages() function"
202+
203+
# Skip repo setup if already configured
204+
if ! check_sgx_repo; then
205+
log_info "Setting up SGX local repository..."
206+
207+
pushd /tmp >> "${LOG_FILE}" 2>&1
208+
log_exec curl -fsSLO \
209+
https://download.01.org/intel-sgx/latest/linux-latest/distro/${PLATFORM}/sgx_debian_local_repo.tgz
210+
211+
local_sum=$(sha256sum sgx_debian_local_repo.tgz | awk '{print $1}')
212+
remote_sum=$(curl -s https://download.01.org/intel-sgx/latest/dcap-latest/linux/SHA256SUM_dcap_1.24.cfg | grep "distro/${PLATFORM}/sgx_debian_local_repo.tgz" | awk '{print $1}')
213+
if [[ "$local_sum" == "$remote_sum" ]]; then
214+
log_info "Checksum matches"
215+
else
216+
log_info "Checksum mismatch!"
217+
fi
218+
219+
log_exec sudo mkdir -p /opt/intel
220+
log_exec sudo tar xzf sgx_debian_local_repo.tgz -C /opt/intel
221+
222+
echo 'deb [signed-by=/etc/apt/keyrings/intel-sgx-keyring.asc arch=amd64] file:///opt/intel/sgx_debian_local_repo bookworm main' \
223+
| sudo tee /etc/apt/sources.list.d/sgx_debian_local_repo.list | tee -a "${LOG_FILE}" > /dev/null
224+
225+
log_exec sudo cp /opt/intel/sgx_debian_local_repo/keys/intel-sgx.key /etc/apt/keyrings/intel-sgx-keyring.asc
226+
popd >> "${LOG_FILE}" 2>&1
227+
else
228+
log_info "SGX repository already configured, skipping setup"
229+
fi
230+
231+
# Install SGX packages only if missing
232+
if ! check_sgx_packages; then
233+
log_info "Installing missing SGX packages..."
234+
log_exec sudo apt-get update
235+
log_exec sudo apt-get install -y libsgx-quote-ex libsgx-dcap-ql
236+
else
237+
log_info "SGX packages already installed, skipping"
238+
fi
239+
240+
# Install build dependencies
241+
log_exec sudo apt-get update --quiet
242+
log_exec sudo apt-get install --quiet -y build-essential python3
243+
log_exec sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1
244+
245+
# Install Intel SGX SDK only if missing
246+
if ! check_sgx_sdk; then
247+
log_info "Installing Intel SGX SDK for Application Developer..."
248+
249+
pushd /opt/intel >> "${LOG_FILE}" 2>&1
250+
log_exec sudo curl -fsSLo sgx_linux_x64_sdk.bin \
251+
https://download.01.org/intel-sgx/latest/linux-latest/distro/${PLATFORM}/sgx_linux_x64_sdk_2.27.100.1.bin
252+
log_exec sudo chmod +x sgx_linux_x64_sdk.bin
253+
log_exec sudo ./sgx_linux_x64_sdk.bin --prefix /opt/intel
254+
255+
# Log environment setup instructions for user
256+
log_info "SGX SDK installation completed successfully."
257+
log_info "IMPORTANT: To use the SGX SDK in your development session:"
258+
log_info " 1. Run: source /opt/intel/sgxsdk/environment"
259+
log_info " 2. This must be done in each shell session where you use SGX"
260+
log_info " 3. Environment variables are session-specific and cannot be exported by this script"
261+
log_info " 4. Consider adding 'source /opt/intel/sgxsdk/environment' to your ~/.bashrc for automatic setup"
262+
popd >> "${LOG_FILE}" 2>&1
263+
else
264+
log_info "SGX SDK already installed, skipping"
265+
fi
266+
267+
# Install Developer packages for Intel SGX only if missing
268+
if ! check_sgx_packages; then
269+
log_info "Installing Intel SGX Developer packages..."
270+
271+
log_exec sudo apt-get install -y libsgx-enclave-common-dev \
272+
libsgx-dcap-ql-dev \
273+
libsgx-dcap-default-qpl-dev \
274+
tee-appraisal-tool
275+
else
276+
log_info "SGX Developer packages already installed, skipping"
277+
fi
278+
279+
log_info "Exiting install_packages() function"
280+
return 0
281+
}
282+
283+
# Validate the installation was successful
284+
validate_installation() {
285+
log_info "Entering validate_installation() function"
286+
287+
local validation_failed=0
288+
289+
# Re-check all components after installation
290+
if ! check_sgx_packages; then
291+
log_info "VALIDATION FAILED: SGX packages not properly installed"
292+
validation_failed=1
293+
fi
294+
295+
if ! check_sgx_sdk; then
296+
log_info "VALIDATION FAILED: SGX SDK not properly installed"
297+
validation_failed=1
298+
fi
299+
300+
if ! check_sgx_repo; then
301+
log_info "VALIDATION FAILED: SGX repository not properly configured"
302+
validation_failed=1
303+
fi
304+
305+
if [ $validation_failed -eq 0 ]; then
306+
log_info "VALIDATION SUCCESS: All SGX components properly installed"
307+
else
308+
log_info "VALIDATION FAILED: Some SGX components failed installation"
309+
log_info "Exiting validate_installation() function"
310+
return 1
311+
fi
312+
313+
log_info "Exiting validate_installation() function"
314+
return 0
315+
}
316+
317+
# Clean up temporary files
318+
cleanup() {
319+
log_info "Entering cleanup() function"
320+
321+
# Clean up any temporary files in /tmp related to SGX installation
322+
if [ -f "/tmp/sgx_debian_local_repo.tgz" ]; then
323+
log_info "Removing temporary SGX repository archive"
324+
rm -f /tmp/sgx_debian_local_repo.tgz
325+
fi
326+
327+
# Additional cleanup can be added here as needed
328+
log_info "Temporary file cleanup completed"
329+
330+
log_info "Exiting cleanup() function"
331+
return 0
332+
}
333+
334+
# Initialize logging
335+
init_log
336+
337+
log_info "Starting idempotency checks..."
338+
339+
# Check if everything is already installed
340+
if check_sgx_packages && check_sgx_sdk && check_sgx_repo; then
341+
log_info "Complete SGX installation detected - no action needed"
342+
echo "Intel SGX for Application Developer is already installed and configured."
343+
exit 0
344+
fi
345+
346+
log_info "Partial or missing SGX installation detected - proceeding with installation"
347+
348+
# Main installation flow using modular functions
349+
350+
log_info "Starting Intel SGX for Application Developer installation..."
351+
352+
# Execute installation steps in modular fashion
353+
platform_detect
354+
if [ $? -ne 0 ]; then
355+
log_info "Platform detection failed"
356+
exit 1
357+
fi
358+
359+
install_packages
360+
if [ $? -ne 0 ]; then
361+
log_info "Package installation failed"
362+
exit 1
363+
fi
364+
365+
validate_installation
366+
if [ $? -ne 0 ]; then
367+
log_info "Installation validation failed"
368+
exit 1
369+
fi
370+
371+
cleanup
372+
if [ $? -ne 0 ]; then
373+
log_info "Cleanup failed"
374+
exit 1
375+
fi
376+
377+
echo "Intel SGX for Application Developer installation completed."

0 commit comments

Comments
 (0)