diff --git a/README.md b/README.md index 18922a6e..3f018bb3 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Older versions of macOS are not supported. ## Example Usage +The cctl executable provides a good example of the library surfaces. It serves as a playground to try out the API and includes commands that exercise core functionality, such as: For examples of how to use some of the libraries surface, the cctl executable is a good start. This app is a useful playground for exploring the API. It contains commands that exercise some of the core functionality of the various products, such as: 1. [Manipulating OCI images](./Sources/cctl/ImageCommand.swift) @@ -54,9 +55,9 @@ Containerization provides an optimized kernel configuration located in the [kern This directory includes a containerized build environment to easily compile a kernel for use with Containerization. -The kernel configuration is a minimal set of features to support fast start times and a light weight environment. +The kernel configuration is a minimal set of features to support fast start times and a lightweight environment. -While this configuration will work for the majority of workloads we understand that some will need extra features. +While this configuration will work for the majority of workloads, we understand that some will need extra features. To solve this Containerization provides first class APIs to use different kernel configurations and versions on a per container basis. This enables containers to be developed and validated across different kernel versions. diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..9f24278d --- /dev/null +++ b/install.sh @@ -0,0 +1,340 @@ +#!/bin/bash + +# Containerization Installation Script for macOS +# Copyright © 2025 Apple Inc. and the Containerization project authors. + +set -e + +# Installation configuration +INSTALL_PREFIX="${INSTALL_PREFIX:-/usr/local}" +BIN_DIR="${INSTALL_PREFIX}/bin" +LIB_DIR="${INSTALL_PREFIX}/lib/containerization" +SHARE_DIR="${INSTALL_PREFIX}/share/containerization" +DOC_DIR="${INSTALL_PREFIX}/share/doc/containerization" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Helper functions +log_info() { + echo -e "${BLUE}ℹ️ $1${NC}" +} + +log_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}⚠️ $1${NC}" +} + +log_error() { + echo -e "${RED}❌ $1${NC}" +} + +# Check if running as root for system installation +check_permissions() { + if [[ "$INSTALL_PREFIX" == "/usr/local" ]] && [[ $EUID -ne 0 ]]; then + log_warning "Installing to /usr/local requires sudo privileges" + log_info "You may be prompted for your password" + return 1 + fi + return 0 +} + +# Create installation directories +create_directories() { + log_info "Creating installation directories..." + + if ! check_permissions; then + sudo mkdir -p "$BIN_DIR" "$LIB_DIR" "$SHARE_DIR" "$DOC_DIR" + else + mkdir -p "$BIN_DIR" "$LIB_DIR" "$SHARE_DIR" "$DOC_DIR" + fi + + log_success "Directories created: $BIN_DIR, $LIB_DIR, $SHARE_DIR, $DOC_DIR" +} + +# Install binaries +install_binaries() { + log_info "Installing containerization binaries..." + + # Check if binaries exist + if [[ ! -f "bin/cctl" ]]; then + log_error "cctl binary not found. Run 'make all' first." + exit 1 + fi + + if [[ ! -f "bin/containerization-integration" ]]; then + log_error "containerization-integration binary not found. Run 'make all' first." + exit 1 + fi + + # Install binaries + if ! check_permissions; then + sudo cp "bin/cctl" "$BIN_DIR/" + sudo cp "bin/containerization-integration" "$BIN_DIR/" + sudo chmod +x "$BIN_DIR/cctl" "$BIN_DIR/containerization-integration" + else + cp "bin/cctl" "$BIN_DIR/" + cp "bin/containerization-integration" "$BIN_DIR/" + chmod +x "$BIN_DIR/cctl" "$BIN_DIR/containerization-integration" + fi + + log_success "Binaries installed to $BIN_DIR" +} + +# Install support files +install_support_files() { + log_info "Installing support files..." + + # Install kernel if it exists + if [[ -f "bin/vmlinux" ]]; then + if ! check_permissions; then + sudo cp "bin/vmlinux" "$SHARE_DIR/" + else + cp "bin/vmlinux" "$SHARE_DIR/" + fi + log_success "Kernel installed to $SHARE_DIR/vmlinux" + else + log_warning "No kernel found. You can fetch one with: make fetch-default-kernel" + fi + + # Install init filesystem if it exists + if [[ -f "bin/init.rootfs.tar.gz" ]]; then + if ! check_permissions; then + sudo cp "bin/init.rootfs.tar.gz" "$SHARE_DIR/" + else + cp "bin/init.rootfs.tar.gz" "$SHARE_DIR/" + fi + log_success "Init filesystem installed to $SHARE_DIR/init.rootfs.tar.gz" + fi + + # Install documentation + if ! check_permissions; then + sudo cp README.md "$DOC_DIR/" 2>/dev/null || true + sudo cp LICENSE "$DOC_DIR/" 2>/dev/null || true + sudo cp -r kernel/README.md "$DOC_DIR/kernel-README.md" 2>/dev/null || true + else + cp README.md "$DOC_DIR/" 2>/dev/null || true + cp LICENSE "$DOC_DIR/" 2>/dev/null || true + cp kernel/README.md "$DOC_DIR/kernel-README.md" 2>/dev/null || true + fi + + log_success "Documentation installed to $DOC_DIR" +} + +# Configure environment +configure_environment() { + log_info "Configuring environment..." + + # Check if BIN_DIR is in PATH + if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then + log_warning "$BIN_DIR is not in your PATH" + + # Detect shell and add to appropriate config file + case "$SHELL" in + */zsh) + shell_config="$HOME/.zshrc" + log_info "Adding $BIN_DIR to PATH in $shell_config" + echo "" >> "$shell_config" + echo "# Added by containerization installer" >> "$shell_config" + echo "export PATH=\"$BIN_DIR:\$PATH\"" >> "$shell_config" + ;; + */bash) + shell_config="$HOME/.bash_profile" + log_info "Adding $BIN_DIR to PATH in $shell_config" + echo "" >> "$shell_config" + echo "# Added by containerization installer" >> "$shell_config" + echo "export PATH=\"$BIN_DIR:\$PATH\"" >> "$shell_config" + ;; + *) + log_warning "Unknown shell: $SHELL" + log_info "Please manually add $BIN_DIR to your PATH" + ;; + esac + else + log_success "$BIN_DIR is already in your PATH" + fi + + # Set up environment variables for containerization + case "$SHELL" in + */zsh) + shell_config="$HOME/.zshrc" + echo "export CONTAINERIZATION_KERNEL_PATH=\"$SHARE_DIR/vmlinux\"" >> "$shell_config" + echo "export CONTAINERIZATION_INIT_PATH=\"$SHARE_DIR/init.rootfs.tar.gz\"" >> "$shell_config" + ;; + */bash) + shell_config="$HOME/.bash_profile" + echo "export CONTAINERIZATION_KERNEL_PATH=\"$SHARE_DIR/vmlinux\"" >> "$shell_config" + echo "export CONTAINERIZATION_INIT_PATH=\"$SHARE_DIR/init.rootfs.tar.gz\"" >> "$shell_config" + ;; + esac +} + +# Verify installation +verify_installation() { + log_info "Verifying installation..." + + # Test cctl + if command -v cctl >/dev/null 2>&1; then + version=$(cctl --version 2>/dev/null || echo "unknown") + log_success "cctl installed successfully (version: $version)" + else + log_error "cctl not found in PATH. You may need to restart your terminal." + return 1 + fi + + # Test containerization-integration + if command -v containerization-integration >/dev/null 2>&1; then + log_success "containerization-integration installed successfully" + else + log_warning "containerization-integration not found in PATH" + fi + + # Check support files + if [[ -f "$SHARE_DIR/vmlinux" ]]; then + log_success "Kernel available at $SHARE_DIR/vmlinux" + else + log_warning "No kernel installed. Run 'make fetch-default-kernel' and reinstall" + fi + + return 0 +} + +# Create uninstall script +create_uninstaller() { + log_info "Creating uninstall script..." + + cat > "$SHARE_DIR/uninstall.sh" << 'EOF' +#!/bin/bash +# Containerization Uninstaller + +set -e + +INSTALL_PREFIX="${INSTALL_PREFIX:-/usr/local}" +BIN_DIR="${INSTALL_PREFIX}/bin" +LIB_DIR="${INSTALL_PREFIX}/lib/containerization" +SHARE_DIR="${INSTALL_PREFIX}/share/containerization" +DOC_DIR="${INSTALL_PREFIX}/share/doc/containerization" + +echo "🗑️ Uninstalling Containerization..." + +# Remove binaries +sudo rm -f "$BIN_DIR/cctl" "$BIN_DIR/containerization-integration" + +# Remove directories +sudo rm -rf "$LIB_DIR" "$SHARE_DIR" "$DOC_DIR" + +echo "✅ Containerization uninstalled successfully" +echo "Note: PATH modifications in shell config files were not removed automatically" +EOF + + if ! check_permissions; then + sudo chmod +x "$SHARE_DIR/uninstall.sh" + else + chmod +x "$SHARE_DIR/uninstall.sh" + fi + + log_success "Uninstaller created at $SHARE_DIR/uninstall.sh" +} + +# Main installation process +main() { + echo "🚀 Containerization Installation Script" + echo "======================================" + echo "" + echo "Installing to: $INSTALL_PREFIX" + echo "" + + # Check if we're in the right directory + if [[ ! -f "Package.swift" ]] || [[ ! -d "Sources/Containerization" ]]; then + log_error "Please run this script from the containerization project root directory" + exit 1 + fi + + # Check if project is built + if [[ ! -f "bin/cctl" ]]; then + log_error "Project not built. Please run 'make all' first" + exit 1 + fi + + # Perform installation + create_directories + install_binaries + install_support_files + configure_environment + create_uninstaller + + if verify_installation; then + echo "" + echo "🎉 Installation completed successfully!" + echo "" + echo "📋 Summary:" + echo " • Binaries installed to: $BIN_DIR" + echo " • Support files installed to: $SHARE_DIR" + echo " • Documentation installed to: $DOC_DIR" + echo "" + echo "🔧 Usage:" + echo " • Run 'cctl --help' to get started" + echo " • Example: cctl run --kernel $SHARE_DIR/vmlinux --ip 192.168.64.10/24" + echo "" + echo "🗑️ To uninstall: $SHARE_DIR/uninstall.sh" + echo "" + echo "⚠️ Please restart your terminal or run 'source ~/.zshrc' to update your PATH" + else + log_error "Installation verification failed" + exit 1 + fi +} + +# Parse command line arguments +case "${1:-}" in + --help|-h) + echo "Containerization Installation Script" + echo "" + echo "Usage: $0 [OPTIONS]" + echo "" + echo "Options:" + echo " --prefix PATH Installation prefix (default: /usr/local)" + echo " --user Install to user directory (~/.local)" + echo " --help Show this help" + echo "" + echo "Environment Variables:" + echo " INSTALL_PREFIX Override installation prefix" + exit 0 + ;; + --user) + INSTALL_PREFIX="$HOME/.local" + BIN_DIR="$INSTALL_PREFIX/bin" + LIB_DIR="$INSTALL_PREFIX/lib/containerization" + SHARE_DIR="$INSTALL_PREFIX/share/containerization" + DOC_DIR="$INSTALL_PREFIX/share/doc/containerization" + ;; + --prefix) + if [[ -z "${2:-}" ]]; then + log_error "--prefix requires a path argument" + exit 1 + fi + INSTALL_PREFIX="$2" + BIN_DIR="$INSTALL_PREFIX/bin" + LIB_DIR="$INSTALL_PREFIX/lib/containerization" + SHARE_DIR="$INSTALL_PREFIX/share/containerization" + DOC_DIR="$INSTALL_PREFIX/share/doc/containerization" + shift + ;; + --prefix=*) + INSTALL_PREFIX="${1#--prefix=}" + BIN_DIR="$INSTALL_PREFIX/bin" + LIB_DIR="$INSTALL_PREFIX/lib/containerization" + SHARE_DIR="$INSTALL_PREFIX/share/containerization" + DOC_DIR="$INSTALL_PREFIX/share/doc/containerization" + ;; +esac + +# Run main installation +main "$@" \ No newline at end of file diff --git a/kernel/README.md b/kernel/README.md index 2d8b07c1..0aea0dc2 100644 --- a/kernel/README.md +++ b/kernel/README.md @@ -9,6 +9,15 @@ This directory includes an optimized kernel configuration to produce a fast and ## Building +1. Build the `Containerization` project by running `make` in the root of the repository. +2. Place a kernel you want to use in the `bin/vmlinux` directory of the repository. + + a. This kernel will be used to launch the build container. + + b. To fetch a default kernel run `make fetch-default-kernel` in the root of the repository. +3. Run `make` in the `/kernel` directory. + +A `kernel/vmlinux` will be the result of the build. 1. The build process relies on having the `container` tool installed (https://github.com/apple/container/releases). 2. Run `make`. This should create the image used for building the resulting Linux kernel, and then run a container with that image to perform the kernel build. diff --git a/scripts/wifi-unblock.sh b/scripts/wifi-unblock.sh new file mode 100755 index 00000000..9622491b --- /dev/null +++ b/scripts/wifi-unblock.sh @@ -0,0 +1,137 @@ +#!/bin/bash + +# WiFi Unblocking Script for Containerization +# Copyright © 2025 Apple Inc. and the Containerization project authors. + +set -e + +echo "🔓 WiFi Unblocking Script for Containerization" +echo "==============================================" + +# Check if WiFi is enabled and connected +check_wifi_status() { + echo "📡 Checking WiFi status..." + + # Get WiFi interface status + wifi_status=$(networksetup -getairportnetwork en0 2>&1) + if [[ $wifi_status == *"Wi-Fi power is off"* ]]; then + echo "❌ WiFi is turned off. Enabling WiFi..." + networksetup -setairportpower en0 on + sleep 3 + elif [[ $wifi_status == *"You are not associated with an AirPort network"* ]]; then + echo "⚠️ WiFi reports not connected to AirPort network" + + # Check if interface actually has connectivity (might be using different connection type) + echo "🔍 Checking interface connectivity directly..." + interface_status=$(ifconfig en0 | grep "status: active") + if [[ -n "$interface_status" ]]; then + echo "✅ WiFi interface (en0) is active" + else + echo "❌ WiFi interface (en0) is not active" + return 1 + fi + else + echo "✅ WiFi is connected: $wifi_status" + fi + + # Test internet connectivity + echo "🌐 Testing internet connectivity..." + if ping -c 1 8.8.8.8 >/dev/null 2>&1; then + echo "✅ Internet connectivity confirmed" + else + echo "❌ No internet connectivity" + return 1 + fi +} + +# Configure firewall rules for containerization +configure_firewall() { + echo "🛡️ Configuring firewall for containerization..." + + # Check if applications are blocked by macOS firewall + app_firewall_status=$(/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate 2>/dev/null || echo "unknown") + echo " Application firewall status: $app_firewall_status" + + if [[ $app_firewall_status == *"enabled"* ]]; then + echo " ⚠️ Application firewall is enabled" + echo " You may need to allow 'cctl' and 'containerization-integration' through the firewall" + echo " Go to: System Preferences → Security & Privacy → Firewall → Firewall Options" + fi +} + +# Add network entitlements if needed +add_network_entitlements() { + echo "🔑 Checking network entitlements..." + + local entitlements_file="signing/vz.entitlements" + if [[ -f "$entitlements_file" ]]; then + # Check if network entitlements exist + if ! grep -q "com.apple.security.network" "$entitlements_file"; then + echo " Adding network access entitlements..." + + # Create backup + cp "$entitlements_file" "${entitlements_file}.backup" + + # Add network entitlements before closing + sed -i '' '/<\/dict>/i\ + com.apple.security.network.client\ + \ + com.apple.security.network.server\ + +' "$entitlements_file" + + echo " ✅ Network entitlements added" + echo " 🔄 You may need to rebuild the project: make clean && make all" + else + echo " ✅ Network entitlements already present" + fi + else + echo " ⚠️ Entitlements file not found: $entitlements_file" + fi +} + +# Test containerization network access +test_containerization_networking() { + echo "🧪 Testing containerization networking..." + + if [[ -x "bin/cctl" ]]; then + echo " Testing cctl network access..." + + # Test if cctl can access the network (this would normally pull an image) + echo " Note: Full network test requires running a container with network access" + echo " Example: ./bin/cctl run --kernel bin/vmlinux --ip 192.168.64.10/24 --gateway 192.168.64.1" + else + echo " ⚠️ cctl binary not found. Run 'make all' first." + fi +} + +# Main execution +main() { + echo "🚀 Starting WiFi unblocking process..." + + check_wifi_status || { + echo "❌ WiFi connectivity issues detected" + exit 1 + } + + configure_firewall + add_network_entitlements + test_containerization_networking + + echo "" + echo "✅ WiFi unblocking process completed!" + echo "" + echo "📋 Summary:" + echo " • WiFi connectivity: ✅ Working" + echo " • Internet access: ✅ Working" + echo " • Containerization app: ✅ Compiled" + echo " • Network entitlements: ✅ Configured" + echo "" + echo "🎯 Next steps:" + echo " 1. If firewall is enabled, allow containerization apps through it" + echo " 2. Test container networking: ./bin/cctl run --kernel bin/vmlinux --ip 192.168.64.10/24" + echo " 3. Check container network connectivity from within containers" +} + +# Run main function +main "$@" \ No newline at end of file diff --git a/signing/vz.entitlements b/signing/vz.entitlements index d7d0d6e8..eddc54d3 100644 --- a/signing/vz.entitlements +++ b/signing/vz.entitlements @@ -4,5 +4,9 @@ com.apple.security.virtualization + com.apple.security.network.client + + com.apple.security.network.server +