1+ #! /bin/bash
2+
3+ # Containerization Installation Script for macOS
4+ # Copyright © 2025 Apple Inc. and the Containerization project authors.
5+
6+ set -e
7+
8+ # Installation configuration
9+ INSTALL_PREFIX=" ${INSTALL_PREFIX:-/ usr/ local} "
10+ BIN_DIR=" ${INSTALL_PREFIX} /bin"
11+ LIB_DIR=" ${INSTALL_PREFIX} /lib/containerization"
12+ SHARE_DIR=" ${INSTALL_PREFIX} /share/containerization"
13+ DOC_DIR=" ${INSTALL_PREFIX} /share/doc/containerization"
14+
15+ # Colors for output
16+ RED=' \033[0;31m'
17+ GREEN=' \033[0;32m'
18+ YELLOW=' \033[1;33m'
19+ BLUE=' \033[0;34m'
20+ NC=' \033[0m' # No Color
21+
22+ # Helper functions
23+ log_info () {
24+ echo -e " ${BLUE} ℹ️ $1 ${NC} "
25+ }
26+
27+ log_success () {
28+ echo -e " ${GREEN} ✅ $1 ${NC} "
29+ }
30+
31+ log_warning () {
32+ echo -e " ${YELLOW} ⚠️ $1 ${NC} "
33+ }
34+
35+ log_error () {
36+ echo -e " ${RED} ❌ $1 ${NC} "
37+ }
38+
39+ # Check if running as root for system installation
40+ check_permissions () {
41+ if [[ " $INSTALL_PREFIX " == " /usr/local" ]] && [[ $EUID -ne 0 ]]; then
42+ log_warning " Installing to /usr/local requires sudo privileges"
43+ log_info " You may be prompted for your password"
44+ return 1
45+ fi
46+ return 0
47+ }
48+
49+ # Create installation directories
50+ create_directories () {
51+ log_info " Creating installation directories..."
52+
53+ if ! check_permissions; then
54+ sudo mkdir -p " $BIN_DIR " " $LIB_DIR " " $SHARE_DIR " " $DOC_DIR "
55+ else
56+ mkdir -p " $BIN_DIR " " $LIB_DIR " " $SHARE_DIR " " $DOC_DIR "
57+ fi
58+
59+ log_success " Directories created: $BIN_DIR , $LIB_DIR , $SHARE_DIR , $DOC_DIR "
60+ }
61+
62+ # Install binaries
63+ install_binaries () {
64+ log_info " Installing containerization binaries..."
65+
66+ # Check if binaries exist
67+ if [[ ! -f " bin/cctl" ]]; then
68+ log_error " cctl binary not found. Run 'make all' first."
69+ exit 1
70+ fi
71+
72+ if [[ ! -f " bin/containerization-integration" ]]; then
73+ log_error " containerization-integration binary not found. Run 'make all' first."
74+ exit 1
75+ fi
76+
77+ # Install binaries
78+ if ! check_permissions; then
79+ sudo cp " bin/cctl" " $BIN_DIR /"
80+ sudo cp " bin/containerization-integration" " $BIN_DIR /"
81+ sudo chmod +x " $BIN_DIR /cctl" " $BIN_DIR /containerization-integration"
82+ else
83+ cp " bin/cctl" " $BIN_DIR /"
84+ cp " bin/containerization-integration" " $BIN_DIR /"
85+ chmod +x " $BIN_DIR /cctl" " $BIN_DIR /containerization-integration"
86+ fi
87+
88+ log_success " Binaries installed to $BIN_DIR "
89+ }
90+
91+ # Install support files
92+ install_support_files () {
93+ log_info " Installing support files..."
94+
95+ # Install kernel if it exists
96+ if [[ -f " bin/vmlinux" ]]; then
97+ if ! check_permissions; then
98+ sudo cp " bin/vmlinux" " $SHARE_DIR /"
99+ else
100+ cp " bin/vmlinux" " $SHARE_DIR /"
101+ fi
102+ log_success " Kernel installed to $SHARE_DIR /vmlinux"
103+ else
104+ log_warning " No kernel found. You can fetch one with: make fetch-default-kernel"
105+ fi
106+
107+ # Install init filesystem if it exists
108+ if [[ -f " bin/init.rootfs.tar.gz" ]]; then
109+ if ! check_permissions; then
110+ sudo cp " bin/init.rootfs.tar.gz" " $SHARE_DIR /"
111+ else
112+ cp " bin/init.rootfs.tar.gz" " $SHARE_DIR /"
113+ fi
114+ log_success " Init filesystem installed to $SHARE_DIR /init.rootfs.tar.gz"
115+ fi
116+
117+ # Install documentation
118+ if ! check_permissions; then
119+ sudo cp README.md " $DOC_DIR /" 2> /dev/null || true
120+ sudo cp LICENSE " $DOC_DIR /" 2> /dev/null || true
121+ sudo cp -r kernel/README.md " $DOC_DIR /kernel-README.md" 2> /dev/null || true
122+ else
123+ cp README.md " $DOC_DIR /" 2> /dev/null || true
124+ cp LICENSE " $DOC_DIR /" 2> /dev/null || true
125+ cp kernel/README.md " $DOC_DIR /kernel-README.md" 2> /dev/null || true
126+ fi
127+
128+ log_success " Documentation installed to $DOC_DIR "
129+ }
130+
131+ # Configure environment
132+ configure_environment () {
133+ log_info " Configuring environment..."
134+
135+ # Check if BIN_DIR is in PATH
136+ if [[ " :$PATH :" != * " :$BIN_DIR :" * ]]; then
137+ log_warning " $BIN_DIR is not in your PATH"
138+
139+ # Detect shell and add to appropriate config file
140+ case " $SHELL " in
141+ * /zsh)
142+ shell_config=" $HOME /.zshrc"
143+ log_info " Adding $BIN_DIR to PATH in $shell_config "
144+ echo " " >> " $shell_config "
145+ echo " # Added by containerization installer" >> " $shell_config "
146+ echo " export PATH=\" $BIN_DIR :\$ PATH\" " >> " $shell_config "
147+ ;;
148+ * /bash)
149+ shell_config=" $HOME /.bash_profile"
150+ log_info " Adding $BIN_DIR to PATH in $shell_config "
151+ echo " " >> " $shell_config "
152+ echo " # Added by containerization installer" >> " $shell_config "
153+ echo " export PATH=\" $BIN_DIR :\$ PATH\" " >> " $shell_config "
154+ ;;
155+ * )
156+ log_warning " Unknown shell: $SHELL "
157+ log_info " Please manually add $BIN_DIR to your PATH"
158+ ;;
159+ esac
160+ else
161+ log_success " $BIN_DIR is already in your PATH"
162+ fi
163+
164+ # Set up environment variables for containerization
165+ case " $SHELL " in
166+ * /zsh)
167+ shell_config=" $HOME /.zshrc"
168+ echo " export CONTAINERIZATION_KERNEL_PATH=\" $SHARE_DIR /vmlinux\" " >> " $shell_config "
169+ echo " export CONTAINERIZATION_INIT_PATH=\" $SHARE_DIR /init.rootfs.tar.gz\" " >> " $shell_config "
170+ ;;
171+ * /bash)
172+ shell_config=" $HOME /.bash_profile"
173+ echo " export CONTAINERIZATION_KERNEL_PATH=\" $SHARE_DIR /vmlinux\" " >> " $shell_config "
174+ echo " export CONTAINERIZATION_INIT_PATH=\" $SHARE_DIR /init.rootfs.tar.gz\" " >> " $shell_config "
175+ ;;
176+ esac
177+ }
178+
179+ # Verify installation
180+ verify_installation () {
181+ log_info " Verifying installation..."
182+
183+ # Test cctl
184+ if command -v cctl > /dev/null 2>&1 ; then
185+ version=$( cctl --version 2> /dev/null || echo " unknown" )
186+ log_success " cctl installed successfully (version: $version )"
187+ else
188+ log_error " cctl not found in PATH. You may need to restart your terminal."
189+ return 1
190+ fi
191+
192+ # Test containerization-integration
193+ if command -v containerization-integration > /dev/null 2>&1 ; then
194+ log_success " containerization-integration installed successfully"
195+ else
196+ log_warning " containerization-integration not found in PATH"
197+ fi
198+
199+ # Check support files
200+ if [[ -f " $SHARE_DIR /vmlinux" ]]; then
201+ log_success " Kernel available at $SHARE_DIR /vmlinux"
202+ else
203+ log_warning " No kernel installed. Run 'make fetch-default-kernel' and reinstall"
204+ fi
205+
206+ return 0
207+ }
208+
209+ # Create uninstall script
210+ create_uninstaller () {
211+ log_info " Creating uninstall script..."
212+
213+ cat > " $SHARE_DIR /uninstall.sh" << 'EOF '
214+ #!/bin/bash
215+ # Containerization Uninstaller
216+
217+ set -e
218+
219+ INSTALL_PREFIX="${INSTALL_PREFIX:-/usr/local}"
220+ BIN_DIR="${INSTALL_PREFIX}/bin"
221+ LIB_DIR="${INSTALL_PREFIX}/lib/containerization"
222+ SHARE_DIR="${INSTALL_PREFIX}/share/containerization"
223+ DOC_DIR="${INSTALL_PREFIX}/share/doc/containerization"
224+
225+ echo "🗑️ Uninstalling Containerization..."
226+
227+ # Remove binaries
228+ sudo rm -f "$BIN_DIR/cctl" "$BIN_DIR/containerization-integration"
229+
230+ # Remove directories
231+ sudo rm -rf "$LIB_DIR" "$SHARE_DIR" "$DOC_DIR"
232+
233+ echo "✅ Containerization uninstalled successfully"
234+ echo "Note: PATH modifications in shell config files were not removed automatically"
235+ EOF
236+
237+ if ! check_permissions; then
238+ sudo chmod +x " $SHARE_DIR /uninstall.sh"
239+ else
240+ chmod +x " $SHARE_DIR /uninstall.sh"
241+ fi
242+
243+ log_success " Uninstaller created at $SHARE_DIR /uninstall.sh"
244+ }
245+
246+ # Main installation process
247+ main () {
248+ echo " 🚀 Containerization Installation Script"
249+ echo " ======================================"
250+ echo " "
251+ echo " Installing to: $INSTALL_PREFIX "
252+ echo " "
253+
254+ # Check if we're in the right directory
255+ if [[ ! -f " Package.swift" ]] || [[ ! -d " Sources/Containerization" ]]; then
256+ log_error " Please run this script from the containerization project root directory"
257+ exit 1
258+ fi
259+
260+ # Check if project is built
261+ if [[ ! -f " bin/cctl" ]]; then
262+ log_error " Project not built. Please run 'make all' first"
263+ exit 1
264+ fi
265+
266+ # Perform installation
267+ create_directories
268+ install_binaries
269+ install_support_files
270+ configure_environment
271+ create_uninstaller
272+
273+ if verify_installation; then
274+ echo " "
275+ echo " 🎉 Installation completed successfully!"
276+ echo " "
277+ echo " 📋 Summary:"
278+ echo " • Binaries installed to: $BIN_DIR "
279+ echo " • Support files installed to: $SHARE_DIR "
280+ echo " • Documentation installed to: $DOC_DIR "
281+ echo " "
282+ echo " 🔧 Usage:"
283+ echo " • Run 'cctl --help' to get started"
284+ echo " • Example: cctl run --kernel $SHARE_DIR /vmlinux --ip 192.168.64.10/24"
285+ echo " "
286+ echo " 🗑️ To uninstall: $SHARE_DIR /uninstall.sh"
287+ echo " "
288+ echo " ⚠️ Please restart your terminal or run 'source ~/.zshrc' to update your PATH"
289+ else
290+ log_error " Installation verification failed"
291+ exit 1
292+ fi
293+ }
294+
295+ # Parse command line arguments
296+ case " ${1:- } " in
297+ --help|-h)
298+ echo " Containerization Installation Script"
299+ echo " "
300+ echo " Usage: $0 [OPTIONS]"
301+ echo " "
302+ echo " Options:"
303+ echo " --prefix PATH Installation prefix (default: /usr/local)"
304+ echo " --user Install to user directory (~/.local)"
305+ echo " --help Show this help"
306+ echo " "
307+ echo " Environment Variables:"
308+ echo " INSTALL_PREFIX Override installation prefix"
309+ exit 0
310+ ;;
311+ --user)
312+ INSTALL_PREFIX=" $HOME /.local"
313+ BIN_DIR=" $INSTALL_PREFIX /bin"
314+ LIB_DIR=" $INSTALL_PREFIX /lib/containerization"
315+ SHARE_DIR=" $INSTALL_PREFIX /share/containerization"
316+ DOC_DIR=" $INSTALL_PREFIX /share/doc/containerization"
317+ ;;
318+ --prefix)
319+ if [[ -z " ${2:- } " ]]; then
320+ log_error " --prefix requires a path argument"
321+ exit 1
322+ fi
323+ INSTALL_PREFIX=" $2 "
324+ BIN_DIR=" $INSTALL_PREFIX /bin"
325+ LIB_DIR=" $INSTALL_PREFIX /lib/containerization"
326+ SHARE_DIR=" $INSTALL_PREFIX /share/containerization"
327+ DOC_DIR=" $INSTALL_PREFIX /share/doc/containerization"
328+ shift
329+ ;;
330+ --prefix=* )
331+ INSTALL_PREFIX=" ${1# --prefix=} "
332+ BIN_DIR=" $INSTALL_PREFIX /bin"
333+ LIB_DIR=" $INSTALL_PREFIX /lib/containerization"
334+ SHARE_DIR=" $INSTALL_PREFIX /share/containerization"
335+ DOC_DIR=" $INSTALL_PREFIX /share/doc/containerization"
336+ ;;
337+ esac
338+
339+ # Run main installation
340+ main " $@ "
0 commit comments