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