This guide provides practical steps for implementing and adopting the novel partitioned Android virtualization approach for various use cases, demonstrating why this method represents a significant advancement over traditional cloud virtualization practices.
# Install required tools
apt update && apt install -y \
unzip wget p7zip-full simg2img proot util-linux lz4 \
jq curl git build-essential
# Create working directory
mkdir -p $HOME/android-partitions && cd $HOME/android-partitions#!/bin/bash
# quick-setup.sh - Rapid partitioned Android environment
set -euo pipefail
DEVICE_MODEL="SM-G965U1" # Example: Galaxy S9+
FIRMWARE_URL="https://example-archive.com/firmware/${DEVICE_MODEL}_firmware.zip"
CELL_NAME="dev_cell"
CELL_BASE="$HOME/android-partitions/${CELL_NAME}"
echo "[+] Setting up partitioned Android environment..."
# 1. Download firmware (if not exists)
if [ ! -f "${DEVICE_MODEL}_firmware.zip" ]; then
echo "[+] Downloading firmware..."
wget -O "${DEVICE_MODEL}_firmware.zip" "${FIRMWARE_URL}"
fi
# 2. Extract system image
echo "[+] Extracting system image..."
EXTRACT_DIR=$(mktemp -d)
cd "${EXTRACT_DIR}"
unzip -j "../${DEVICE_MODEL}_firmware.zip" "AP*.tar.md5"
tar -xf *.tar.md5 "system.img.lz4"
lz4 -d "system.img.lz4" system.img.raw
simg2img system.img.raw system.img
# 3. Create partition structure
echo "[+] Creating partition structure..."
mkdir -p "${CELL_BASE}"/{system_ro,upper,work,merged}
mount -o loop "${EXTRACT_DIR}/system.img" "${CELL_BASE}/system_ro"
# 4. Setup OverlayFS
mount -t overlay overlay \
-o lowerdir="${CELL_BASE}/system_ro",upperdir="${CELL_BASE}/upper",workdir="${CELL_BASE}/work" \
"${CELL_BASE}/merged"
# 5. Create entry script
cat > "${CELL_BASE}/enter.sh" << 'EOF'
#!/bin/bash
exec proot \
-r "${CELL_BASE}/merged" \
-b /dev -b /proc -b /sys \
-w / /system/bin/sh "$@"
EOF
chmod +x "${CELL_BASE}/enter.sh"
echo "[+] Setup complete! Enter environment with: ${CELL_BASE}/enter.sh"#!/bin/bash
# multi-tenant-setup.sh - Multiple isolated Android environments
create_tenant_cell() {
local tenant_name="$1"
local base_image="$2"
local cell_path="$HOME/tenants/${tenant_name}"
mkdir -p "${cell_path}"/{upper,work,merged}
# Mount shared read-only base
mount -t overlay overlay \
-o lowerdir="${base_image}",upperdir="${cell_path}/upper",workdir="${cell_path}/work" \
"${cell_path}/merged"
# Create tenant-specific entry point
cat > "${cell_path}/enter" << EOF
#!/bin/bash
echo "Entering ${tenant_name} development environment..."
exec proot -r "${cell_path}/merged" \
-b /dev -b /proc -b /sys \
-b "\$HOME:/host-home" \
-w / /system/bin/sh "\$@"
EOF
chmod +x "${cell_path}/enter"
echo "Created tenant cell: ${tenant_name}"
}
# Setup multiple development environments
BASE_SYSTEM="/opt/android-systems/android10-base.img"
create_tenant_cell "frontend-team" "${BASE_SYSTEM}"
create_tenant_cell "backend-team" "${BASE_SYSTEM}"
create_tenant_cell "qa-team" "${BASE_SYSTEM}"
create_tenant_cell "staging" "${BASE_SYSTEM}"
# Usage:
# $HOME/tenants/frontend-team/enter
# $HOME/tenants/qa-team/enter -c "run_tests.sh"# .github/workflows/android-partition-ci.yml
name: Android Partition CI
on: [push, pull_request]
jobs:
test-android-partition:
runs-on: self-hosted-android
strategy:
matrix:
android_version: [10, 11, 12]
device_model: [SM-G965U1, SM-G973F]
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup partition environment
run: |
CELL_NAME="ci-${{ matrix.android_version }}-${{ matrix.device_model }}"
if [ ! -d "$HOME/ci-cells/${CELL_NAME}" ]; then
./scripts/create-ci-cell.sh \
--android-version ${{ matrix.android_version }} \
--device-model ${{ matrix.device_model }} \
--cell-name ${CELL_NAME}
fi
- name: Run tests in partition
run: |
CELL_NAME="ci-${{ matrix.android_version }}-${{ matrix.device_model }}"
$HOME/ci-cells/${CELL_NAME}/enter -c "
cd ${GITHUB_WORKSPACE}
export ANDROID_VERSION=${{ matrix.android_version }}
export DEVICE_MODEL=${{ matrix.device_model }}
./run-android-tests.sh
"
- name: Collect test results
if: always()
run: |
CELL_NAME="ci-${{ matrix.android_version }}-${{ matrix.device_model }}"
cp $HOME/ci-cells/${CELL_NAME}/upper/data/test-results/* ./test-results/
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results-${{ matrix.android_version }}-${{ matrix.device_model }}
path: test-results/#!/bin/bash
# edge-deploy.sh - Deploy partitioned Android to edge devices
deploy_to_edge() {
local edge_device="$1"
local application_bundle="$2"
echo "Deploying to edge device: ${edge_device}"
# 1. Transfer base system image (one-time)
if ! ssh "${edge_device}" "[ -f /opt/android-base.img ]"; then
echo "Transferring base system image..."
scp ./android-base.img "${edge_device}:/opt/android-base.img"
fi
# 2. Create application partition
ssh "${edge_device}" bash << EOF
mkdir -p /opt/partitions/app-{upper,work,merged}
# Mount application partition
mount -t overlay overlay \\
-o lowerdir=/opt/android-base.img,upperdir=/opt/partitions/app-upper,workdir=/opt/partitions/app-work \\
/opt/partitions/app-merged
# Create application entry point
cat > /opt/partitions/run-app.sh << 'SCRIPT'
#!/bin/bash
exec proot \\
-r /opt/partitions/app-merged \\
-b /dev -b /proc -b /sys \\
-w /data/app \\
/system/bin/sh /data/app/start.sh
SCRIPT
chmod +x /opt/partitions/run-app.sh
EOF
# 3. Deploy application
echo "Deploying application bundle..."
scp -r "${application_bundle}"/* "${edge_device}:/opt/partitions/app-upper/data/app/"
# 4. Start application
ssh "${edge_device}" "/opt/partitions/run-app.sh"
echo "Deployment complete to ${edge_device}"
}
# Deploy to multiple edge devices
deploy_to_edge "edge-device-001.local" "./my-edge-app"
deploy_to_edge "edge-device-002.local" "./my-edge-app"
deploy_to_edge "edge-device-003.local" "./my-edge-app"#!/bin/bash
# optimize-memory.sh - Memory optimization for partitioned environments
optimize_partition_memory() {
local cell_path="$1"
# Enable memory deduplication for overlays
echo "Optimizing memory usage for ${cell_path}..."
# Use compressed overlay storage
mkdir -p "${cell_path}/upper-compressed"
mount -t squashfs -o compress "${cell_path}/upper" "${cell_path}/upper-compressed"
# Configure PRoot for minimal memory usage
cat > "${cell_path}/enter-optimized" << 'EOF'
#!/bin/bash
# Memory-optimized entry point
export PROOT_NO_SECCOMP=1
export PROOT_TMP_DIR=/tmp/proot-$$
mkdir -p $PROOT_TMP_DIR
exec proot \
-r "${CELL_PATH}/merged" \
-b /dev -b /proc -b /sys \
-t $PROOT_TMP_DIR \
--kill-on-exit \
-w / /system/bin/sh "$@"
# Cleanup on exit
trap "rm -rf $PROOT_TMP_DIR" EXIT
EOF
chmod +x "${cell_path}/enter-optimized"
}#!/bin/bash
# optimize-storage.sh - Storage optimization strategies
setup_storage_optimization() {
local base_system="$1"
local shared_cache="/opt/android-cache"
# Create shared package cache
mkdir -p "${shared_cache}/packages"
mkdir -p "${shared_cache}/data"
# Setup deduplicated storage
cat > ./create-optimized-cell.sh << 'EOF'
#!/bin/bash
CELL_NAME="$1"
CELL_PATH="/opt/cells/${CELL_NAME}"
mkdir -p "${CELL_PATH}"/{upper,work,merged}
# Use hardlinks for common files to save space
cp -al /opt/android-cache/packages/* "${CELL_PATH}/upper/" 2>/dev/null || true
# Mount with compression
mount -t overlay overlay \
-o lowerdir=/opt/android-base.img,upperdir="${CELL_PATH}/upper",workdir="${CELL_PATH}/work",compress=lz4 \
"${CELL_PATH}/merged"
echo "Optimized cell created: ${CELL_NAME}"
EOF
chmod +x ./create-optimized-cell.sh
}#!/bin/bash
# monitor-partitions.sh - Monitor partition health and resource usage
monitor_partitions() {
echo "=== Android Partition Health Report ==="
echo "Generated: $(date)"
echo
for cell_dir in /opt/cells/*/; do
if [ -d "$cell_dir" ]; then
cell_name=$(basename "$cell_dir")
echo "Cell: $cell_name"
# Check mount status
if mountpoint -q "${cell_dir}/merged"; then
echo " Status: Active"
# Memory usage
mem_usage=$(pmap -x $(pgrep -f "proot.*${cell_dir}") 2>/dev/null | tail -1 | awk '{print $3}')
echo " Memory Usage: ${mem_usage:-0} KB"
# Storage usage
upper_size=$(du -sh "${cell_dir}/upper" 2>/dev/null | cut -f1)
echo " Storage (Upper): $upper_size"
# Process count
proc_count=$(pgrep -f "proot.*${cell_dir}" | wc -l)
echo " Active Processes: $proc_count"
else
echo " Status: Inactive"
fi
echo
fi
done
}
# Run monitoring
monitor_partitions
# Set up continuous monitoring
if [ "$1" = "--continuous" ]; then
while true; do
clear
monitor_partitions
sleep 30
done
fi#!/bin/bash
# backup-partitions.sh - Automated partition backup system
backup_partition() {
local cell_name="$1"
local backup_dir="/opt/backups/partitions"
local timestamp=$(date +%Y%m%d_%H%M%S)
mkdir -p "${backup_dir}/${cell_name}"
echo "Backing up partition: $cell_name"
# Create incremental backup of upper layer
rsync -avz --link-dest="${backup_dir}/${cell_name}/latest" \
"/opt/cells/${cell_name}/upper/" \
"${backup_dir}/${cell_name}/${timestamp}/"
# Update latest symlink
ln -sfn "${timestamp}" "${backup_dir}/${cell_name}/latest"
# Compress old backups (older than 7 days)
find "${backup_dir}/${cell_name}" -type d -name "20*" -mtime +7 -exec tar -czf {}.tar.gz {} \; -exec rm -rf {} \;
echo "Backup completed: ${backup_dir}/${cell_name}/${timestamp}"
}
# Backup all active partitions
for cell in /opt/cells/*/; do
if [ -d "$cell" ]; then
cell_name=$(basename "$cell")
backup_partition "$cell_name"
fi
done# Dockerfile.android-partition - Hybrid approach
FROM ubuntu:20.04
# Install partition tools
RUN apt-get update && apt-get install -y \
proot simg2img lz4 unzip wget \
&& rm -rf /var/lib/apt/lists/*
# Copy partition management scripts
COPY scripts/ /opt/partition-scripts/
COPY android-base.img /opt/android-base.img
# Setup partition environment
RUN /opt/partition-scripts/setup-container-partition.sh
# Entry point that enters Android partition
ENTRYPOINT ["/opt/partition-scripts/enter-partition.sh"]# android-partition-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: android-partition-pod
spec:
containers:
- name: android-partition
image: your-registry/android-partition:latest
securityContext:
privileged: true # Required for mount operations
volumeMounts:
- name: android-base
mountPath: /opt/android-base.img
readOnly: true
- name: partition-storage
mountPath: /opt/partitions
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "1Gi"
cpu: "500m"
volumes:
- name: android-base
hostPath:
path: /shared/android-base.img
- name: partition-storage
emptyDir:
sizeLimit: 10Gi#!/bin/bash
# migrate-from-vm.sh - Migrate VM-based Android development to partitions
migrate_vm_to_partition() {
local vm_name="$1"
local vm_export_path="$2"
echo "Migrating VM: $vm_name to Android partition..."
# 1. Export VM filesystem
echo "Exporting VM filesystem..."
vboxmanage export "$vm_name" --output "$vm_export_path"
# 2. Extract Android system
echo "Extracting Android system from VM..."
# ... extraction logic based on VM format
# 3. Create partition
echo "Creating optimized partition..."
./create-partition.sh --from-vm "$vm_export_path" --name "${vm_name}-partition"
# 4. Performance comparison
echo "Running performance comparison..."
./benchmark-vm-vs-partition.sh "$vm_name" "${vm_name}-partition"
}#!/bin/bash
# migrate-from-container.sh - Migrate container-based workflows to partitions
migrate_container_to_partition() {
local image_name="$1"
local partition_name="$2"
echo "Migrating container: $image_name to Android partition..."
# 1. Extract application from container
docker create --name temp-container "$image_name"
docker export temp-container | tar -xC /tmp/container-export/
docker rm temp-container
# 2. Create Android partition with application
./create-partition.sh --name "$partition_name"
cp -r /tmp/container-export/app/* "/opt/cells/${partition_name}/upper/data/app/"
# 3. Create compatibility wrapper
cat > "/opt/cells/${partition_name}/run-app" << 'EOF'
#!/bin/bash
# Compatibility wrapper for containerized application
exec /opt/cells/${partition_name}/enter -c "cd /data/app && ./start.sh"
EOF
chmod +x "/opt/cells/${partition_name}/run-app"
echo "Migration completed. Run: /opt/cells/${partition_name}/run-app"
}#!/bin/bash
# security-hardening.sh - Security best practices for partitions
harden_partition() {
local cell_path="$1"
# 1. Set restrictive permissions
chmod 750 "$cell_path"
chown root:android-users "$cell_path"
# 2. Create security policy
cat > "${cell_path}/security-policy.sh" << 'EOF'
#!/bin/bash
# Security policy for Android partition
# Restrict network access
export PROOT_NETWORK_RESTRICT=1
# Enable audit logging
export PROOT_AUDIT_LOG=/var/log/proot-audit.log
# Restrict file system access
export PROOT_CHROOT_STRICT=1
# Apply security context
exec proot \
-r "${CELL_PATH}/merged" \
-b /dev -b /proc \
--kill-on-exit \
-w / /system/bin/sh "$@"
EOF
# 3. Setup monitoring
echo "Setting up security monitoring for $cell_path..."
# Add monitoring configuration
}#!/bin/bash
# performance-tuning.sh - Optimize partition performance
tune_partition_performance() {
local cell_path="$1"
# 1. Optimize I/O scheduler
echo "deadline" > /sys/block/sda/queue/scheduler
# 2. Configure memory management
echo 1 > /proc/sys/vm/drop_caches
sysctl vm.swappiness=10
# 3. Optimize partition mount options
mount -o remount,noatime,compress=lz4 "${cell_path}/merged"
# 4. Configure PRoot optimizations
export PROOT_NO_SECCOMP=1
export PROOT_LOADER_32=/usr/lib/proot/loader-32.so
export PROOT_LOADER=/usr/lib/proot/loader.so
echo "Performance tuning applied to $cell_path"
}This implementation guide demonstrates the practical advantages of partitioned Android virtualization:
- Faster deployment - Instant environment creation vs. minutes for VMs
- Lower resource usage - Minimal overhead compared to traditional virtualization
- Better compatibility - Native Android environment vs. emulation
- Enhanced security - Firmware-based integrity and overlay isolation
- Simplified management - Direct integration with existing infrastructure
The approach fills a unique niche in the virtualization landscape, particularly for Android-centric development, edge computing, and resource-constrained environments where traditional virtualization methods are too heavyweight or incompatible.