diff --git a/.github/workflows/build-iso.yml b/.github/workflows/build-iso.yml index 6a51ffb..bd26184 100644 --- a/.github/workflows/build-iso.yml +++ b/.github/workflows/build-iso.yml @@ -12,6 +12,8 @@ on: paths: - 'iso/**' - 'packages/**' + - 'scripts/**' + - 'docs/branding/**' - 'Makefile' - '.github/workflows/build-iso.yml' pull_request: @@ -19,180 +21,231 @@ on: paths: - 'iso/**' - 'packages/**' + - 'scripts/**' + - 'docs/branding/**' - 'Makefile' workflow_dispatch: - inputs: - iso_type: - description: 'ISO type to build' - required: true - default: 'offline' - type: choice - options: - - netinst - - offline - - both env: DEBIAN_FRONTEND: noninteractive jobs: - build-packages: - name: Build Debian Packages + validate: + name: Validate runs-on: ubuntu-24.04 + container: + image: debian:bookworm steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install build dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - dpkg-dev \ - devscripts \ - debhelper \ - fakeroot \ - gnupg - - - name: Build cortex-archive-keyring - run: | - cd packages/cortex-archive-keyring - dpkg-buildpackage -us -uc -b - - - name: Build cortex-core + - name: Install git run: | - cd packages/cortex-core - dpkg-buildpackage -us -uc -b + apt-get update + apt-get install -y git sudo make shellcheck - - name: Build cortex-full - run: | - cd packages/cortex-full - dpkg-buildpackage -us -uc -b + - name: Checkout + uses: actions/checkout@v4 - - name: Upload packages - uses: actions/upload-artifact@v4 - with: - name: debian-packages - path: packages/*.deb - retention-days: 7 + - name: Run validation + run: make validate build-iso: - name: Build ISO Image - runs-on: ubuntu-24.04 - needs: build-packages + name: Build ISO (${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} + needs: validate strategy: + fail-fast: false matrix: - arch: [amd64] - # arm64 builds require self-hosted runner with ARM + include: + - arch: amd64 + runner: ubuntu-24.04 + - arch: arm64 + runner: ubuntu-24.04-arm steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Download packages - uses: actions/download-artifact@v4 + - name: Free disk space + uses: jlumbroso/free-disk-space@main with: - name: debian-packages - path: packages/ - - - name: Install live-build dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - live-build \ - debootstrap \ - squashfs-tools \ - xorriso \ - isolinux \ - syslinux-efi \ - grub-pc-bin \ - grub-efi-amd64-bin \ - mtools \ - dosfstools - - - name: Configure live-build + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + + - name: Additional cleanup run: | - cd iso/live-build - chmod +x auto/* - sudo lb config + echo "=== Additional cleanup ===" + sudo rm -rf /home/runner/.rustup || true + sudo rm -rf /home/runner/.cargo || true + sudo rm -rf /usr/share/swift || true + sudo rm -rf /usr/lib/jvm || true + sudo rm -rf /usr/local/julia* || true + sudo rm -rf /usr/local/share/chromium || true + sudo rm -rf /usr/lib/google-cloud-sdk || true + sudo rm -rf /opt/hostedtoolcache/CodeQL || true + echo "=== Disk space after additional cleanup ===" + df -h - - name: Copy packages to chroot - run: | - mkdir -p iso/live-build/config/packages.chroot/ - cp packages/*.deb iso/live-build/config/packages.chroot/ + - name: Checkout + uses: actions/checkout@v4 - - name: Build ISO + - name: Build in Debian container run: | - cd iso/live-build - sudo lb build 2>&1 | tee build.log - - - name: Generate checksums + # Use xz compression for releases (smaller), lz4 for PR/branch builds (faster) + if [[ "${{ github.ref }}" == refs/tags/v* ]]; then + COMPRESSION="xz" + else + COMPRESSION="lz4" + fi + docker run --rm --privileged \ + -v "${{ github.workspace }}:/workspace" \ + -w /workspace \ + -e ARCH=${{ matrix.arch }} \ + -e SQUASHFS_COMP=$COMPRESSION \ + -e DEBIAN_FRONTEND=noninteractive \ + debian:bookworm /bin/bash -c ' + set -e + ./scripts/install-deps.sh + make check-deps + make iso + ' + + - name: List output + if: always() run: | - cd iso/live-build - sha256sum *.iso > SHA256SUMS - sha512sum *.iso > SHA512SUMS + ls -la output/ || echo "No output directory" + ls -la build/ || echo "No build directory" - name: Upload ISO uses: actions/upload-artifact@v4 with: name: cortex-linux-${{ matrix.arch }} path: | - iso/live-build/*.iso - iso/live-build/SHA256SUMS - iso/live-build/SHA512SUMS + output/*.iso + output/*.sha256 retention-days: 14 + - name: Upload packages + uses: actions/upload-artifact@v4 + with: + name: packages-${{ matrix.arch }} + path: output/*.deb + retention-days: 14 + + - name: Upload SBOM + uses: actions/upload-artifact@v4 + with: + name: sbom-${{ matrix.arch }} + path: output/sbom/ + retention-days: 14 + continue-on-error: true + - name: Upload build log if: always() uses: actions/upload-artifact@v4 with: name: build-log-${{ matrix.arch }} - path: iso/live-build/build.log + path: build.log retention-days: 7 + test-iso: + name: Test ISO (${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} + needs: build-iso + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + runner: ubuntu-24.04 + - arch: arm64 + runner: ubuntu-24.04-arm + steps: + - name: Download ISO + uses: actions/download-artifact@v4 + with: + name: cortex-linux-${{ matrix.arch }} + + - name: Verify checksums + run: | + ls -la + for iso in *.iso; do + if [ -f "${iso}.sha256" ]; then + sha256sum -c "${iso}.sha256" + fi + done + + - name: Check ISO structure + run: | + sudo apt-get update + sudo apt-get install -y xorriso + for iso in *.iso; do + echo "=== Checking $iso ===" + xorriso -indev "$iso" -find / -maxdepth 1 2>/dev/null | head -20 + done + release: name: Create Release runs-on: ubuntu-24.04 - needs: build-iso + needs: [build-iso, test-iso] if: startsWith(github.ref, 'refs/tags/v') permissions: contents: write steps: - - name: Download ISO artifacts + - name: Download all ISO artifacts uses: actions/download-artifact@v4 with: pattern: cortex-linux-* merge-multiple: true + path: release/ - name: Download packages uses: actions/download-artifact@v4 with: - name: debian-packages + pattern: packages-* + merge-multiple: true + path: release/ + + - name: Download SBOMs + uses: actions/download-artifact@v4 + with: + pattern: sbom-* + merge-multiple: true + path: release/sbom/ + continue-on-error: true + + - name: Generate combined checksums + run: | + cd release + sha256sum *.iso *.deb > SHA256SUMS 2>/dev/null || sha256sum *.iso > SHA256SUMS + sha512sum *.iso *.deb > SHA512SUMS 2>/dev/null || sha512sum *.iso > SHA512SUMS - name: Create Release uses: softprops/action-gh-release@v1 with: files: | - *.iso - *.deb - SHA256SUMS - SHA512SUMS + release/*.iso + release/*.deb + release/SHA256SUMS + release/SHA512SUMS + release/sbom/* body: | ## Cortex Linux ${{ github.ref_name }} - + ### Downloads - - **cortex-linux-*-amd64-offline.iso** - Full offline installer - - **cortex-linux-*-amd64-netinst.iso** - Minimal network installer - + - **cortex-linux-*.iso** - Cortex Linux ISO + - **cortex-branding_*.deb** - Branding package (standalone install) + ### Verification ```bash sha256sum -c SHA256SUMS ``` - + ### Quick Start - 1. Write ISO to USB: `dd if=cortex-linux-*.iso of=/dev/sdX bs=4M status=progress` + 1. Write ISO to USB: `sudo dd if=cortex-linux-*.iso of=/dev/sdX bs=4M status=progress oflag=sync` 2. Boot from USB - 3. Follow installation prompts - + 3. Select "Live Boot" or "Install" + ### Documentation - See https://cortexlinux.com/docs for full documentation. + See https://github.com/cortexlinux/cortex-distro for documentation. draft: false prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }} diff --git a/.github/workflows/reproducible-builds.yml b/.github/workflows/reproducible-builds.yml deleted file mode 100644 index 15064a0..0000000 --- a/.github/workflows/reproducible-builds.yml +++ /dev/null @@ -1,313 +0,0 @@ -name: Reproducible Builds - -on: - push: - branches: [main] - paths: - - 'packages/**' - pull_request: - branches: [main] - paths: - - 'packages/**' - workflow_dispatch: - inputs: - package: - description: 'Package to build (or "all")' - required: false - default: 'all' - -env: - DEBIAN_FRONTEND: noninteractive - SOURCE_DATE_EPOCH: 0 - -jobs: - build-first: - name: Build (First Pass) - runs-on: ubuntu-24.04 - outputs: - packages: ${{ steps.list.outputs.packages }} - steps: - - uses: actions/checkout@v4 - - - name: Install build dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - sbuild \ - schroot \ - debootstrap \ - devscripts \ - debhelper \ - fakeroot \ - mmdebstrap \ - diffoscope \ - reprotest - - - name: Setup sbuild - run: | - sudo sbuild-createchroot \ - --include=devscripts,debhelper,fakeroot \ - trixie \ - /srv/chroot/trixie-amd64 \ - http://deb.debian.org/debian - - - name: List packages to build - id: list - run: | - if [ "${{ github.event.inputs.package }}" = "all" ] || [ -z "${{ github.event.inputs.package }}" ]; then - packages=$(ls -d packages/*/ | xargs -n1 basename | jq -R -s -c 'split("\n")[:-1]') - else - packages='["${{ github.event.inputs.package }}"]' - fi - echo "packages=$packages" >> $GITHUB_OUTPUT - - - name: Build packages (first pass) - run: | - mkdir -p build-1 - for pkg in packages/*/; do - pkg_name=$(basename $pkg) - echo "Building $pkg_name (pass 1)..." - - cd $pkg - SOURCE_DATE_EPOCH=$(git log -1 --format=%ct) \ - sbuild \ - --chroot=trixie-amd64 \ - --arch=amd64 \ - --build-dir=../../build-1 \ - --no-clean-source \ - --extra-repository="deb http://deb.debian.org/debian trixie main" - cd ../.. - done - - - name: Upload first build - uses: actions/upload-artifact@v4 - with: - name: build-pass-1 - path: build-1/*.deb - retention-days: 1 - - - name: Upload buildinfo - uses: actions/upload-artifact@v4 - with: - name: buildinfo-pass-1 - path: build-1/*.buildinfo - retention-days: 30 - - build-second: - name: Build (Second Pass) - runs-on: ubuntu-24.04 - needs: build-first - steps: - - uses: actions/checkout@v4 - - - name: Install build dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - sbuild \ - schroot \ - debootstrap \ - devscripts \ - debhelper \ - fakeroot \ - mmdebstrap - - - name: Setup sbuild - run: | - sudo sbuild-createchroot \ - --include=devscripts,debhelper,fakeroot \ - trixie \ - /srv/chroot/trixie-amd64 \ - http://deb.debian.org/debian - - - name: Build packages (second pass) - run: | - mkdir -p build-2 - for pkg in packages/*/; do - pkg_name=$(basename $pkg) - echo "Building $pkg_name (pass 2)..." - - cd $pkg - SOURCE_DATE_EPOCH=$(git log -1 --format=%ct) \ - sbuild \ - --chroot=trixie-amd64 \ - --arch=amd64 \ - --build-dir=../../build-2 \ - --no-clean-source \ - --extra-repository="deb http://deb.debian.org/debian trixie main" - cd ../.. - done - - - name: Upload second build - uses: actions/upload-artifact@v4 - with: - name: build-pass-2 - path: build-2/*.deb - retention-days: 1 - - compare: - name: Compare Builds - runs-on: ubuntu-24.04 - needs: [build-first, build-second] - steps: - - uses: actions/checkout@v4 - - - name: Install diffoscope - run: | - sudo apt-get update - sudo apt-get install -y diffoscope - - - name: Download first build - uses: actions/download-artifact@v4 - with: - name: build-pass-1 - path: build-1 - - - name: Download second build - uses: actions/download-artifact@v4 - with: - name: build-pass-2 - path: build-2 - - - name: Compare builds - id: compare - run: | - mkdir -p diffoscope-output - reproducible=true - - for deb1 in build-1/*.deb; do - filename=$(basename $deb1) - deb2="build-2/$filename" - - if [ ! -f "$deb2" ]; then - echo "❌ Missing in second build: $filename" - reproducible=false - continue - fi - - # Calculate checksums - sum1=$(sha256sum "$deb1" | cut -d' ' -f1) - sum2=$(sha256sum "$deb2" | cut -d' ' -f1) - - if [ "$sum1" = "$sum2" ]; then - echo "✅ Reproducible: $filename" - else - echo "❌ Not reproducible: $filename" - reproducible=false - - # Generate diffoscope report - diffoscope \ - --html "diffoscope-output/${filename%.deb}.html" \ - --text "diffoscope-output/${filename%.deb}.txt" \ - "$deb1" "$deb2" || true - fi - done - - if [ "$reproducible" = "true" ]; then - echo "status=pass" >> $GITHUB_OUTPUT - else - echo "status=fail" >> $GITHUB_OUTPUT - fi - - - name: Upload diffoscope reports - if: steps.compare.outputs.status == 'fail' - uses: actions/upload-artifact@v4 - with: - name: diffoscope-reports - path: diffoscope-output/ - retention-days: 30 - - - name: Check reproducibility gate - if: steps.compare.outputs.status == 'fail' - run: | - echo "::error::Builds are not reproducible. See diffoscope reports." - exit 1 - - lintian: - name: Lintian Checks - runs-on: ubuntu-24.04 - needs: build-first - steps: - - name: Install lintian - run: | - sudo apt-get update - sudo apt-get install -y lintian - - - name: Download build - uses: actions/download-artifact@v4 - with: - name: build-pass-1 - path: build - - - name: Run lintian - run: | - mkdir -p lintian-output - - for deb in build/*.deb; do - filename=$(basename $deb) - echo "Checking $filename..." - - lintian \ - --pedantic \ - --info \ - --display-info \ - "$deb" | tee "lintian-output/${filename%.deb}.txt" - done - - # Check for errors - if grep -rq "^E:" lintian-output/; then - echo "::error::Lintian found errors" - exit 1 - fi - - - name: Upload lintian reports - uses: actions/upload-artifact@v4 - with: - name: lintian-reports - path: lintian-output/ - retention-days: 30 - - autopkgtest: - name: Autopkgtest - runs-on: ubuntu-24.04 - needs: build-first - steps: - - uses: actions/checkout@v4 - - - name: Install autopkgtest - run: | - sudo apt-get update - sudo apt-get install -y autopkgtest qemu-system-x86 qemu-utils - - - name: Download build - uses: actions/download-artifact@v4 - with: - name: build-pass-1 - path: build - - - name: Run autopkgtest - run: | - mkdir -p autopkgtest-output - - for deb in build/*.deb; do - filename=$(basename $deb) - pkg_name=${filename%%_*} - - # Check if package has tests - if [ -d "packages/$pkg_name/debian/tests" ]; then - echo "Testing $pkg_name..." - - autopkgtest \ - "$deb" \ - -- null 2>&1 | tee "autopkgtest-output/${pkg_name}.txt" || true - else - echo "No tests for $pkg_name" - fi - done - - - name: Upload test results - uses: actions/upload-artifact@v4 - with: - name: autopkgtest-results - path: autopkgtest-output/ - retention-days: 30 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73cab0a --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Build artifacts +build/ +output/ +.cache/ + +# Built packages (regenerated during build) +iso/live-build/config/packages.chroot/*.deb + +# Temporary files +*.tmp +*.bak +*.swp +*.swo +*~ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# IDE files +.vscode/ +.idea/ +*.code-workspace + +# Logs +*.log diff --git a/Makefile b/Makefile index d03853e..c12cf2e 100644 --- a/Makefile +++ b/Makefile @@ -1,183 +1,193 @@ # Cortex Linux Distribution Build System # Copyright 2025 AI Venture Holdings LLC # SPDX-License-Identifier: Apache-2.0 - +# +# This Makefile provides targets for building Cortex Linux ISOs, +# packages, and managing the distribution. +# +# Usage: +# make help - Show available targets +# make iso - Build ISO +# make validate - Validate preseed files +# make clean - Clean build artifacts + +.PHONY: all help iso iso-arm64 \ + validate clean clean-all clean-hooks sync-config test check-deps install-deps \ + preseed-check provision-check lint branding-package \ + build-package packages chroot-shell config + +# Configuration SHELL := /bin/bash -.PHONY: all iso iso-netinst iso-offline package sbom clean test help - -# Build configuration -CODENAME := trixie -ARCH := amd64 -VERSION := 0.1.0 -BUILD_DATE := $(shell date +%Y%m%d) -ISO_NAME := cortex-linux-$(VERSION)-$(ARCH)-$(BUILD_DATE) +.SHELLFLAGS := -eu -o pipefail -c # Directories BUILD_DIR := build -ISO_DIR := iso/live-build OUTPUT_DIR := output -PACKAGES_DIR := packages -# Colors for output -GREEN := \033[0;32m -YELLOW := \033[1;33m -RED := \033[0;31m -NC := \033[0m +# ISO configuration +ISO_NAME := cortex-linux +ISO_VERSION := $(shell date +%Y%m%d) +DEBIAN_VERSION := bookworm +ARCH ?= amd64 + +# Build script +BUILD_SCRIPT := scripts/build.sh + +# Default target +all: help + +# ============================================================================= +# Help +# ============================================================================= help: @echo "Cortex Linux Distribution Build System" + @echo "Copyright 2025 AI Venture Holdings LLC (Apache-2.0)" @echo "" - @echo "Usage: make [target]" + @echo "ISO Build Targets:" + @echo " make iso Build Cortex Linux ISO" + @echo " make iso-arm64 Build ARM64 ISO" @echo "" - @echo "Targets:" - @echo " iso Build full offline ISO (default)" - @echo " iso-netinst Build minimal network installer ISO" - @echo " iso-offline Build full offline ISO with package pool" - @echo " package Build all meta-packages" - @echo " package PKG=x Build specific package (cortex-core, cortex-full, cortex-archive-keyring)" - @echo " sbom Generate Software Bill of Materials" - @echo " test Run build verification tests" - @echo " clean Remove build artifacts" - @echo " deps Install build dependencies" + @echo "Validation Targets:" + @echo " make validate Run all validation checks" + @echo " make preseed-check Validate preseed syntax" + @echo " make provision-check Validate provisioning scripts" + @echo " make lint Run shellcheck on scripts" @echo "" + @echo "Package Targets:" + @echo " make packages Build all .deb packages" + @echo " make build-package PKG=name Build specific package" + @echo " Available: cortex-branding cortex-core cortex-full cortex-secops" + @echo "" + @echo "Branding Targets:" + @echo " make branding-package Build cortex-branding .deb package" + @echo " (To install: sudo apt install ./output/cortex-branding_*.deb)" + @echo "" + @echo "Development Targets:" + @echo " make chroot-shell Enter interactive shell in chroot filesystem" + @echo "" + @echo "Utility Targets:" + @echo " make install-deps Install build dependencies (requires sudo)" + @echo " make check-deps Check build dependencies" + @echo " make clean Clean build artifacts" + @echo " make clean-all Clean everything including output" + @echo " make test Run test suite" + @echo "" + @echo "Configuration:" + @echo " ISO_NAME = $(ISO_NAME)" + @echo " ISO_VERSION = $(ISO_VERSION)" + @echo " DEBIAN_VERSION = $(DEBIAN_VERSION)" + @echo " ARCH = $(ARCH)" + +# ============================================================================= +# Dependencies & Validation +# ============================================================================= + +install-deps: + @sudo scripts/install-deps.sh + +check-deps: + @$(BUILD_SCRIPT) check-deps + +preseed-check: + @$(BUILD_SCRIPT) validate preseed + +provision-check: + @$(BUILD_SCRIPT) validate provision + +lint: + @$(BUILD_SCRIPT) validate lint + +validate: + @$(BUILD_SCRIPT) validate all + +# ============================================================================= +# ISO Build Targets +# ============================================================================= + +iso: check-deps validate + @ARCH=$(ARCH) DEBIAN_VERSION=$(DEBIAN_VERSION) ISO_NAME=$(ISO_NAME) ISO_VERSION=$(ISO_VERSION) \ + $(BUILD_SCRIPT) build + +iso-arm64: + $(MAKE) ARCH=arm64 iso + +# ============================================================================= +# Clean Targets +# ============================================================================= -all: iso - -# Install build dependencies (requires root) -deps: - @echo -e "$(GREEN)Installing build dependencies...$(NC)" - apt-get update - apt-get install -y \ - live-build \ - debootstrap \ - squashfs-tools \ - xorriso \ - isolinux \ - syslinux-efi \ - grub-pc-bin \ - grub-efi-amd64-bin \ - mtools \ - dosfstools \ - dpkg-dev \ - devscripts \ - debhelper \ - fakeroot \ - gnupg \ - syft \ - cyclonedx-cli \ - python3-pip - @echo -e "$(GREEN)Dependencies installed$(NC)" - -# Configure live-build -$(BUILD_DIR)/.configured: - @echo -e "$(GREEN)Configuring live-build...$(NC)" - mkdir -p $(BUILD_DIR) - cd $(ISO_DIR) && lb config \ - --distribution $(CODENAME) \ - --archive-areas "main contrib non-free non-free-firmware" \ - --architectures $(ARCH) \ - --binary-images iso-hybrid \ - --bootloaders "grub-efi,syslinux" \ - --debian-installer live \ - --debian-installer-gui false \ - --iso-application "Cortex Linux" \ - --iso-publisher "AI Venture Holdings LLC" \ - --iso-volume "Cortex Linux $(VERSION)" \ - --memtest none \ - --security true \ - --updates true \ - --backports true \ - --apt-indices true \ - --apt-recommends true \ - --apt-source-archives false \ - --cache true \ - --checksums sha256 \ - --clean \ - --color \ - --compression xz \ - --debconf-frontend noninteractive \ - --debootstrap-options "--variant=minbase" \ - --firmware-binary true \ - --firmware-chroot true \ - --initramfs live-boot \ - --interactive false \ - --linux-packages "linux-image linux-headers" \ - --mode debian \ - --system live \ - --bootappend-live "boot=live components quiet splash" - touch $@ - -# Build ISO -iso: iso-offline - -iso-netinst: $(BUILD_DIR)/.configured - @echo -e "$(GREEN)Building network installer ISO...$(NC)" - cd $(ISO_DIR) && sudo lb build 2>&1 | tee $(BUILD_DIR)/build-netinst.log - mkdir -p $(OUTPUT_DIR) - mv $(ISO_DIR)/live-image-$(ARCH).hybrid.iso $(OUTPUT_DIR)/$(ISO_NAME)-netinst.iso - cd $(OUTPUT_DIR) && sha256sum $(ISO_NAME)-netinst.iso > $(ISO_NAME)-netinst.iso.sha256 - @echo -e "$(GREEN)ISO built: $(OUTPUT_DIR)/$(ISO_NAME)-netinst.iso$(NC)" - -iso-offline: $(BUILD_DIR)/.configured package - @echo -e "$(GREEN)Building full offline ISO...$(NC)" - cd $(ISO_DIR) && sudo lb build 2>&1 | tee $(BUILD_DIR)/build-offline.log - mkdir -p $(OUTPUT_DIR) - mv $(ISO_DIR)/live-image-$(ARCH).hybrid.iso $(OUTPUT_DIR)/$(ISO_NAME)-offline.iso - cd $(OUTPUT_DIR) && sha256sum $(ISO_NAME)-offline.iso > $(ISO_NAME)-offline.iso.sha256 - @echo -e "$(GREEN)ISO built: $(OUTPUT_DIR)/$(ISO_NAME)-offline.iso$(NC)" - -# Build packages -package: +clean: + @$(BUILD_SCRIPT) clean + +clean-all: + @$(BUILD_SCRIPT) clean-all + +clean-hooks: + @$(BUILD_SCRIPT) clean-hooks + +sync-config: + @$(BUILD_SCRIPT) sync + +# ============================================================================= +# Test +# ============================================================================= + +test: + @$(BUILD_SCRIPT) test + +# ============================================================================= +# Packages +# ============================================================================= + +# Build all packages +packages: + @$(BUILD_SCRIPT) build-package all + +# Build specific package (usage: make build-package PKG=cortex-branding) +build-package: ifdef PKG - @echo -e "$(GREEN)Building package: $(PKG)$(NC)" - cd $(PACKAGES_DIR)/$(PKG) && dpkg-buildpackage -us -uc -b + @$(BUILD_SCRIPT) build-package $(PKG) else - @echo -e "$(GREEN)Building all packages...$(NC)" - for pkg in cortex-archive-keyring cortex-core cortex-full; do \ - echo -e "$(YELLOW)Building $$pkg...$(NC)"; \ - cd $(PACKAGES_DIR)/$$pkg && dpkg-buildpackage -us -uc -b && cd ../..; \ - done + @$(BUILD_SCRIPT) build-package all endif - @echo -e "$(GREEN)Packages built$(NC)" - -# Generate SBOM -sbom: - @echo -e "$(GREEN)Generating Software Bill of Materials...$(NC)" - mkdir -p $(OUTPUT_DIR)/sbom - @if [ -f "$(OUTPUT_DIR)/$(ISO_NAME)-offline.iso" ]; then \ - echo "Generating SBOM for ISO..."; \ - syft $(OUTPUT_DIR)/$(ISO_NAME)-offline.iso -o cyclonedx-json > $(OUTPUT_DIR)/sbom/$(ISO_NAME).cdx.json; \ - syft $(OUTPUT_DIR)/$(ISO_NAME)-offline.iso -o spdx-json > $(OUTPUT_DIR)/sbom/$(ISO_NAME).spdx.json; \ - else \ - echo "No ISO found, generating SBOM from package lists..."; \ - ./scripts/generate-sbom.sh $(OUTPUT_DIR)/sbom; \ - fi - @echo -e "$(GREEN)SBOM generated in $(OUTPUT_DIR)/sbom/$(NC)" -# Run tests -test: - @echo -e "$(GREEN)Running build verification tests...$(NC)" - ./tests/verify-iso.sh $(OUTPUT_DIR)/$(ISO_NAME)-offline.iso || true - ./tests/verify-packages.sh || true - ./tests/verify-preseed.sh || true - @echo -e "$(GREEN)Tests complete$(NC)" +# ============================================================================= +# Branding +# ============================================================================= -# Clean build artifacts -clean: - @echo -e "$(YELLOW)Cleaning build artifacts...$(NC)" - cd $(ISO_DIR) && sudo lb clean --purge 2>/dev/null || true - rm -rf $(BUILD_DIR) - rm -rf $(OUTPUT_DIR) - find $(PACKAGES_DIR) -name "*.deb" -delete - find $(PACKAGES_DIR) -name "*.buildinfo" -delete - find $(PACKAGES_DIR) -name "*.changes" -delete - @echo -e "$(GREEN)Clean complete$(NC)" - -# Development helpers -dev-shell: - @echo "Starting development shell in build environment..." - cd $(ISO_DIR) && sudo lb shell +# Build cortex-branding package (use 'make packages PKG=cortex-branding' instead) +branding-package: + @$(BUILD_SCRIPT) build-package cortex-branding + +# To install branding on a system, use the package: +# sudo apt install ./output/cortex-branding_*.deb +# Or: +# sudo dpkg -i output/cortex-branding_*.deb +# ============================================================================= +# Development Helpers +# ============================================================================= + +# Enter interactive shell inside the chroot filesystem chroot-shell: - @echo "Starting chroot shell..." - cd $(ISO_DIR) && sudo lb chroot + @if [ -d "$(BUILD_DIR)/chroot" ]; then \ + echo "Entering chroot..."; \ + sudo chroot "$(BUILD_DIR)/chroot" /bin/bash; \ + else \ + echo "ERROR: Chroot not found at $(BUILD_DIR)/chroot"; \ + echo "Run 'make iso' first to create it"; \ + exit 1; \ + fi + +# ============================================================================= +# Configuration +# ============================================================================= + +config: + @echo "Current Configuration:" + @echo " ISO_NAME = $(ISO_NAME)" + @echo " ISO_VERSION = $(ISO_VERSION)" + @echo " DEBIAN_VERSION = $(DEBIAN_VERSION)" + @echo " ARCH = $(ARCH) (supported: amd64, arm64)" + @echo " BUILD_DIR = $(BUILD_DIR)" + @echo " OUTPUT_DIR = $(OUTPUT_DIR)" diff --git a/README.md b/README.md index 568f181..25db4bd 100644 --- a/README.md +++ b/README.md @@ -21,18 +21,14 @@ git clone https://github.com/cortexlinux/cortex-distro.git cd cortex-distro -# Install dependencies (requires sudo) -sudo apt-get install -y live-build debootstrap squashfs-tools xorriso \ - isolinux syslinux-efi grub-pc-bin grub-efi-amd64-bin \ - mtools dosfstools dpkg-dev devscripts debhelper fakeroot gnupg - -# Build offline ISO (recommended) -chmod +x scripts/build.sh -sudo ./scripts/build.sh offline - -# Or use Makefile -make deps # Install dependencies -make iso # Build ISO +# Install dependencies +sudo ./scripts/install-deps.sh + +# Build ISO +make iso + +# Build for ARM64 +make iso ARCH=arm64 ``` ### Output @@ -40,15 +36,11 @@ make iso # Build ISO After a successful build: ``` output/ -├── cortex-linux-0.1.0-amd64-offline.iso # Bootable ISO -├── cortex-linux-0.1.0-amd64-offline.iso.sha256 -├── packages/ -│ ├── cortex-archive-keyring_*.deb -│ ├── cortex-core_*.deb -│ └── cortex-full_*.deb +├── cortex-linux-0.1.0-amd64.iso # Bootable ISO +├── cortex-linux-0.1.0-amd64.iso.sha256 └── sbom/ - ├── cortex-linux-0.1.0.cdx.json # CycloneDX SBOM - └── cortex-linux-0.1.0.spdx.json # SPDX SBOM + ├── cortex-linux-0.1.0.cdx.json # CycloneDX SBOM + └── cortex-linux-0.1.0.spdx.json # SPDX SBOM ``` ## Architecture @@ -59,17 +51,21 @@ cortex-distro/ │ ├── live-build/ # Debian live-build configs │ │ ├── auto/ # Build automation scripts │ │ └── config/ # Package lists, hooks, includes -│ └── preseed/ # Automated installation preseeds +│ ├── preseed/ # Automated installation preseeds +│ └── provisioning/ # First-boot setup scripts ├── packages/ # Debian package definitions -│ ├── cortex-archive-keyring/ # GPG keyring package -│ ├── cortex-core/ # Minimal installation meta-package -│ └── cortex-full/ # Full installation meta-package +│ └── cortex-branding/ # Branding package (self-contained) +│ ├── source/ # Master logo images +│ ├── Makefile # Asset generator +│ └── debian/ # Package build files ├── repository/ # APT repository tooling │ └── scripts/ # repo-manage.sh ├── sbom/ # SBOM generation (CycloneDX/SPDX) -├── branding/ # Plymouth theme, wallpapers +├── docs/ # Documentation +│ └── branding/ # Brand guidelines and asset docs ├── scripts/ # Build automation -│ └── build.sh # Master build script +│ ├── build.sh # Master build script +│ └── install-deps.sh # Dependency installer ├── tests/ # Verification tests │ ├── verify-iso.sh │ ├── verify-packages.sh @@ -85,26 +81,22 @@ cortex-distro/ |-----------|-------------| | **ISO Builder** | Reproducible ISO image pipeline using Debian live-build | | **APT Repository** | Signed package repository with GPG key management | -| **Meta-packages** | cortex-core (minimal), cortex-full (complete) | | **First-boot** | Preseed automation and idempotent provisioning | | **SBOM** | Software Bill of Materials (CycloneDX/SPDX) | -## Installation Profiles +## Included Software -### cortex-core (Minimal) +The Cortex Linux ISO includes: - Base system with Python 3.11+ +- GNOME desktop environment - Security sandbox (Firejail, AppArmor) -- SSH server -- Cortex package manager dependencies - -### cortex-full (Recommended) -Everything in cortex-core plus: -- Docker and container tools +- Container runtime (Docker, Podman) - Network security (nftables, fail2ban) - Monitoring (Prometheus node exporter) - Web server (nginx) and TLS (certbot) -- GPU support prerequisites +- GPU support prerequisites (NVIDIA, AMD) - Modern CLI tools (htop, btop, fzf, ripgrep, bat) +- AI/ML prerequisites (numpy, scipy, pandas) ## Automated Installation @@ -143,7 +135,7 @@ Signed-By: /usr/share/keyrings/cortex-archive-keyring.gpg ./repository/scripts/repo-manage.sh init # Add package -./repository/scripts/repo-manage.sh add packages/cortex-core_0.1.0-1_all.deb +./repository/scripts/repo-manage.sh add packages/cortex-branding_1.0.0_all.deb # Publish (sign and generate metadata) CORTEX_GPG_KEY_ID=ABCD1234 ./repository/scripts/repo-manage.sh publish @@ -174,14 +166,12 @@ CORTEX_GPG_KEY_ID=ABCD1234 ./repository/scripts/repo-manage.sh publish ```bash make help # Show all targets -make iso # Build full offline ISO -make iso-netinst # Build minimal network installer -make package # Build all Debian packages -make package PKG=cortex-core # Build specific package +make iso # Build ISO +make iso ARCH=arm64 # Build ARM64 ISO make sbom # Generate SBOM make test # Run verification tests make clean # Remove build artifacts -make deps # Install build dependencies +make install-deps # Install build dependencies ``` ## Topics Covered @@ -207,7 +197,7 @@ This repository implements 9 major topics from the Cortex Linux planning: - Root/sudo access ### Target Hardware -- x86_64 (amd64) architecture +- x86_64 (amd64) or ARM64 architecture - UEFI or Legacy BIOS - 2GB+ RAM (4GB+ recommended) - 20GB+ storage diff --git a/docs/branding/BRAND-GUIDELINES.md b/docs/branding/BRAND-GUIDELINES.md new file mode 100644 index 0000000..3784289 --- /dev/null +++ b/docs/branding/BRAND-GUIDELINES.md @@ -0,0 +1,256 @@ +# Cortex Linux Brand Guidelines + +Official brand guidelines for Cortex Linux visual identity. + +## Brand Essence + +Cortex Linux is an AI-powered Linux distribution that combines the stability of Debian with cutting-edge AI capabilities. The brand should convey: + +- **Intelligence** - Neural networks, AI, machine learning +- **Power** - Professional, capable, enterprise-ready +- **Elegance** - Modern, clean, minimal +- **Trust** - Reliable, secure, stable + +## Logo + +### Primary Logo + +The Cortex logo is a "CX" monogram in a circular badge, featuring: +- **CX monogram**: Bold, stylized letters representing "Cortex" +- **Circular badge**: A ring with a purple-to-cyan gradient (matching the brand color palette) +- **Circuit board traces**: Horizontal lines extending from the badge, representing technology and connectivity +- **Two versions**: Light version (white/light background) and Dark version (dark space-like background) + +The design conveys: +- AI and machine learning capabilities through the circuit aesthetics +- Modern, tech-forward identity fitting the "Cortex" name +- Professional and enterprise-ready appearance + +### Logo Variations + +| Variant | Usage | +|---------|-------| +| Full color (dark bg) | Primary use on dark backgrounds | +| Full color (light bg) | Light backgrounds | +| Transparent | Overlay on images or colored backgrounds | +| Icon only | Favicons, app icons, small contexts | + +### Source Files + +Master logo files are located in `packages/cortex-branding/source/`: +- `cx-logo-dark.png` - Logo on dark space-like background +- `cx-logo-transparent.png` - Logo with transparent background + +### Clear Space + +Maintain minimum clear space equal to the height of the "O" in CORTEX around all sides of the logo. + +### Minimum Size + +- Full logo: 120px width minimum +- Icon only: 24px minimum + +## Color Palette + +### Primary Colors + +| Name | Hex | RGB | Usage | +|------|-----|-----|-------| +| **Cortex Purple** | `#6B21A8` | 107, 33, 168 | Primary brand color | +| **Electric Cyan** | `#06B6D4` | 6, 182, 212 | Accent, highlights | +| **Deep Space** | `#0F0F23` | 15, 15, 35 | Dark backgrounds | + +### Secondary Colors + +| Name | Hex | RGB | Usage | +|------|-----|-----|-------| +| Light Purple | `#A855F7` | 168, 85, 247 | Hover states, gradients | +| Dark Purple | `#4C1D95` | 76, 29, 149 | Shadows, depth | +| Light Cyan | `#22D3EE` | 34, 211, 238 | Highlights, active states | +| Dark Cyan | `#0891B2` | 8, 145, 178 | Pressed states | + +### Neutral Colors + +| Name | Hex | RGB | Usage | +|------|-----|-----|-------| +| White | `#FFFFFF` | 255, 255, 255 | Light text, backgrounds | +| Light Gray | `#F8FAFC` | 248, 250, 252 | Light mode backgrounds | +| Gray 100 | `#E2E8F0` | 226, 232, 240 | Borders, dividers | +| Gray 300 | `#94A3B8` | 148, 163, 184 | Muted text | +| Gray 500 | `#64748B` | 100, 116, 139 | Secondary text | +| Gray 700 | `#334155` | 51, 65, 85 | Dark mode text | +| Dark Gray | `#1E1E3F` | 30, 30, 63 | Dark surfaces | +| Black | `#0A0A18` | 10, 10, 24 | Deepest dark | + +### Semantic Colors + +| Name | Hex | Usage | +|------|-----|-------| +| Success | `#10B981` | Positive actions, confirmations | +| Warning | `#FBBF24` | Caution, attention needed | +| Error | `#EF4444` | Errors, destructive actions | +| Info | `#3B82F6` | Informational messages | + +## Typography + +### System Fonts + +```css +/* Sans-serif (UI, body text) */ +font-family: 'Inter', 'Segoe UI', 'Roboto', sans-serif; + +/* Monospace (code, terminal) */ +font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; +``` + +### Font Weights + +- **Light (300)**: Large headings +- **Regular (400)**: Body text +- **Medium (500)**: Subheadings +- **Semibold (600)**: Buttons, labels +- **Bold (700)**: Headings, emphasis + +### Scale + +| Name | Size | Line Height | Usage | +|------|------|-------------|-------| +| Display | 48px | 1.1 | Hero headings | +| H1 | 36px | 1.2 | Page titles | +| H2 | 28px | 1.3 | Section headings | +| H3 | 22px | 1.4 | Subsections | +| Body | 16px | 1.5 | Paragraphs | +| Small | 14px | 1.5 | Captions | +| Tiny | 12px | 1.4 | Labels | + +## Iconography + +### Style + +- Line weight: 1.5px +- Corner radius: 2px +- Grid: 24x24 base +- Style: Rounded, modern + +### System Icons + +Use Lucide icons or similar for consistency: +- Simple, recognizable +- Consistent stroke weight +- Rounded corners + +## Gradients + +### Primary Gradient +```css +background: linear-gradient(135deg, #6B21A8 0%, #06B6D4 100%); +``` + +### Dark Gradient +```css +background: linear-gradient(180deg, #0F0F23 0%, #0A0A18 100%); +``` + +### Subtle Gradient (for cards) +```css +background: linear-gradient(135deg, #1E1E3F 0%, #0F0F23 100%); +``` + +## Components + +### Buttons + +``` +Primary: #6B21A8 background, white text +Secondary: transparent, #6B21A8 border +Ghost: transparent, #94A3B8 text +Danger: #EF4444 background, white text +``` + +### Cards + +``` +Background: #1E1E3F (dark) or #FFFFFF (light) +Border: 1px solid rgba(107, 33, 168, 0.2) +Border radius: 12px +Shadow: 0 4px 20px rgba(0, 0, 0, 0.15) +``` + +### Input Fields + +``` +Background: #0F0F23 (dark) or #F8FAFC (light) +Border: 1px solid #2D2D5A +Focus border: #06B6D4 +Border radius: 8px +``` + +## Animation + +### Timing + +- **Fast**: 150ms (hover, focus) +- **Normal**: 250ms (transitions) +- **Slow**: 400ms (complex animations) + +### Easing + +```css +/* Default */ +transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + +/* Enter */ +transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + +/* Exit */ +transition-timing-function: cubic-bezier(0.4, 0, 1, 1); +``` + +## Usage Examples + +### Dark Theme (Default) + +```css +:root { + --bg-primary: #0F0F23; + --bg-secondary: #1E1E3F; + --text-primary: #E2E8F0; + --text-secondary: #94A3B8; + --accent-primary: #6B21A8; + --accent-secondary: #06B6D4; +} +``` + +### Light Theme + +```css +:root { + --bg-primary: #FFFFFF; + --bg-secondary: #F8FAFC; + --text-primary: #0F172A; + --text-secondary: #64748B; + --accent-primary: #6B21A8; + --accent-secondary: #0891B2; +} +``` + +## File Formats + +### Logos +- SVG: Primary format for web/print +- PNG: Raster fallback (2x, 3x) +- ICO: Favicons + +### Images +- PNG: Screenshots, complex graphics +- WebP: Web optimization +- JPEG: Photos (quality 85%) + +## Don'ts + +- Don't stretch or distort the logo +- Don't change logo colors arbitrarily +- Don't add effects (shadows, glows) to logo +- Don't place logo on busy backgrounds +- Don't use unapproved color combinations +- Don't use fonts outside the family diff --git a/docs/branding/GDM-THEMING.md b/docs/branding/GDM-THEMING.md new file mode 100644 index 0000000..6129108 --- /dev/null +++ b/docs/branding/GDM-THEMING.md @@ -0,0 +1,73 @@ +# GDM Branding + +Cortex Linux GDM (GNOME Display Manager) branding is included in the `cortex-branding` package. + +## Automatic Installation + +GDM branding is automatically configured when you install the package: + +```bash +sudo apt install ./cortex-branding_*.deb +# or +sudo dpkg -i cortex-branding_*.deb +``` + +The package includes: + +| Component | Installed To | Description | +|-----------|--------------|-------------| +| GDM CSS theme | `/usr/share/gnome-shell/theme/Cortex/gnome-shell.css` | Login screen styling | +| GDM dconf | `/etc/dconf/db/gdm.d/01-cortex-branding` | GDM settings (logo, banner) | +| Logo SVG | `/usr/share/cortex/logos/cortex-logo-light.svg` | Login screen logo | +| Background | `/usr/share/backgrounds/cortex/minimal-dark.png` | Login background | + +## What Gets Configured + +The package's `postinst` script: +1. Registers the Cortex GDM theme with `update-alternatives` +2. Updates the dconf database for GDM settings +3. Compiles GSettings schemas + +## Manual Testing + +After installation: + +```bash +# Restart GDM to apply changes +sudo systemctl restart gdm3 + +# Or switch to tty and back +# Ctrl+Alt+F3, login, then: sudo systemctl restart gdm3 +``` + +## Troubleshooting + +### Changes not appearing +1. Clear GDM cache: `sudo rm -rf /var/lib/gdm3/.cache` +2. Rebuild dconf: `sudo dconf update` +3. Restart GDM: `sudo systemctl restart gdm3` + +### Login screen shows Debian branding +1. Check alternatives: `update-alternatives --display gdm3-theme.css` +2. Ensure Cortex theme has highest priority + +### Reverting to default +```bash +sudo apt remove cortex-branding +# or manually: +sudo update-alternatives --remove gdm3-theme.css /usr/share/gnome-shell/theme/Cortex/gnome-shell.css +sudo dconf update +sudo systemctl restart gdm3 +``` + +## Customizing + +To modify GDM theming, edit the files in `packages/cortex-branding/`: +- `usr/share/gnome-shell/theme/Cortex/gnome-shell.css` - CSS styling +- `etc/dconf/db/gdm.d/01-cortex-branding` - GDM dconf settings + +Then rebuild the package: +```bash +cd packages/cortex-branding +dpkg-buildpackage -us -uc -b +``` diff --git a/docs/branding/GRUB-ASSETS.md b/docs/branding/GRUB-ASSETS.md new file mode 100644 index 0000000..e4070a9 --- /dev/null +++ b/docs/branding/GRUB-ASSETS.md @@ -0,0 +1,53 @@ +# GRUB Theme Assets + +Required image assets for the Cortex Linux GRUB theme. + +## Required Files + +| File | Dimensions | Description | +|------|------------|-------------| +| `background.png` | 1920x1080 | Boot menu background | +| `select_c.png` | 10x40 | Selection bar center (tileable) | +| `select_e.png` | 10x40 | Selection bar east cap | +| `select_n.png` | 40x10 | Selection bar north cap | +| `select_ne.png` | 10x10 | Selection bar northeast corner | +| `select_nw.png` | 10x10 | Selection bar northwest corner | +| `select_s.png` | 40x10 | Selection bar south cap | +| `select_se.png` | 10x10 | Selection bar southeast corner | +| `select_sw.png` | 10x10 | Selection bar southwest corner | +| `select_w.png` | 10x40 | Selection bar west cap | +| `terminal_box_c.png` | 10x10 | Terminal background center | +| `terminal_box_*.png` | varies | Terminal box edges (8 files) | +| `scrollbar_thumb.png` | 10x30 | Scrollbar thumb | +| `scrollbar_frame.png` | 10x100 | Scrollbar track | + +## Icons (Optional) + +Place in `icons/` subdirectory: +- `cortex.png` - Cortex Linux entry +- `debian.png` - Debian fallback +- `linux.png` - Generic Linux +- `windows.png` - Windows (dual-boot) +- `recovery.png` - Recovery mode +- `settings.png` - UEFI settings + +## Background Concept + +The background should feature: +- Dark gradient (#0F0F23 to #0A0A15) +- Subtle neural network pattern overlay (10% opacity) +- Cortex logo watermark in bottom-right (15% opacity) +- Slight purple glow effect in center + +## Installation + +```bash +# Install theme +sudo cp -r cortex /boot/grub/themes/ + +# Update GRUB config +echo 'GRUB_THEME="/boot/grub/themes/cortex/theme.txt"' | sudo tee -a /etc/default/grub + +# Regenerate GRUB +sudo update-grub +``` diff --git a/docs/branding/PLYMOUTH-ASSETS.md b/docs/branding/PLYMOUTH-ASSETS.md new file mode 100644 index 0000000..c4e9296 --- /dev/null +++ b/docs/branding/PLYMOUTH-ASSETS.md @@ -0,0 +1,28 @@ +# Plymouth Theme Assets + +Minimal Cortex Linux Plymouth theme - CX logo centered on pure black background. + +## Required Files + +| File | Dimensions | Description | +|------|------------|-------------| +| `logo.png` | 300x300 | CX logo with purple-cyan gradient ring | +| `entry.png` | 300x40 | Password entry box (shown when needed) | +| `bullet.png` | 15x15 | Password bullet character | + +## Design + +- **Background**: Pure black (#000000) +- **Logo**: CX monogram with gradient ring, perfectly centered +- **No animations, no progress bar, no wordmark** - clean minimal boot splash + +## Asset Generation + +Assets are generated from `packages/cortex-branding/source/cx-logo-primary.png` using Make. + +```bash +cd packages/cortex-branding +make # Only rebuild changed assets +make clean # Remove generated assets +make all # Force rebuild everything +``` diff --git a/docs/branding/WALLPAPERS-ASSETS.md b/docs/branding/WALLPAPERS-ASSETS.md new file mode 100644 index 0000000..ee3e7f3 --- /dev/null +++ b/docs/branding/WALLPAPERS-ASSETS.md @@ -0,0 +1,53 @@ +# Desktop Wallpaper Assets + +Cortex Linux desktop wallpapers with CX branding. + +## Available Wallpapers + +| File | Description | +|------|-------------| +| `minimal-dark.png` | Dark solid background with CX logo (default) | +| `circuit-board.png` | Circuit board pattern with CX logo | + +Both wallpapers feature a subtle CX logo centered on the background. + +## Color Palette + +### Dark Theme +``` +Background: #0F0F23 +Surface: #1E1E3F +Border: #2D2D5A +``` + +### Accent Colors +``` +Primary Purple: #6B21A8 +Light Purple: #A855F7 +Electric Cyan: #06B6D4 +Light Cyan: #22D3EE +``` + +## Installation Path + +``` +/usr/share/backgrounds/cortex/ +├── minimal-dark.png (default) +└── circuit-board.png + +/usr/share/gnome-background-properties/ +└── cortex-wallpapers.xml +``` + +## Default Wallpaper + +`minimal-dark.png` is set as the default wallpaper via GNOME dconf configuration. + +## Asset Generation + +```bash +cd packages/cortex-branding +make # Only rebuild changed assets +make clean # Remove generated assets +make all # Force rebuild everything +``` diff --git a/iso/live-build/auto/build b/iso/live-build/auto/build deleted file mode 100755 index d70d30d..0000000 --- a/iso/live-build/auto/build +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Cortex Linux live-build auto/build -# Copyright 2025 AI Venture Holdings LLC -# SPDX-License-Identifier: Apache-2.0 - -set -e - -echo "================================================" -echo " Cortex Linux ISO Build" -echo " Started: $(date)" -echo "================================================" - -# Run the build -lb build noauto "${@}" - -BUILD_STATUS=$? - -echo "================================================" -echo " Build completed: $(date)" -echo " Status: ${BUILD_STATUS}" -echo "================================================" - -exit ${BUILD_STATUS} diff --git a/iso/live-build/auto/clean b/iso/live-build/auto/clean deleted file mode 100755 index c2e2c19..0000000 --- a/iso/live-build/auto/clean +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# Cortex Linux live-build auto/clean -# Copyright 2025 AI Venture Holdings LLC -# SPDX-License-Identifier: Apache-2.0 - -set -e - -echo "Cleaning Cortex Linux build environment..." - -lb clean noauto "${@}" - -# Clean additional artifacts -rm -f config/binary config/bootstrap config/chroot config/common config/source 2>/dev/null || true -rm -rf .build 2>/dev/null || true -rm -f *.iso *.hybrid.iso *.contents *.files *.packages *.zsync 2>/dev/null || true -rm -f chroot.* binary.* source.* 2>/dev/null || true - -echo "Clean complete" diff --git a/iso/live-build/auto/config b/iso/live-build/auto/config deleted file mode 100755 index df650db..0000000 --- a/iso/live-build/auto/config +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# Cortex Linux live-build auto/config -# This script is called by lb config to set build parameters -# Copyright 2025 AI Venture Holdings LLC -# SPDX-License-Identifier: Apache-2.0 - -set -e - -# Cortex Linux build configuration -CODENAME="trixie" -ARCH="amd64" -VERSION="0.1.0" - -lb config noauto \ - --distribution "${CODENAME}" \ - --parent-distribution "${CODENAME}" \ - --parent-debian-installer-distribution "${CODENAME}" \ - --archive-areas "main contrib non-free non-free-firmware" \ - --architectures "${ARCH}" \ - --binary-images iso-hybrid \ - --bootloaders "grub-efi,syslinux" \ - --debian-installer-distribution "${CODENAME}" \ - --debian-installer live \ - --debian-installer-gui false \ - --iso-application "Cortex Linux" \ - --iso-preparer "Cortex Linux Build System" \ - --iso-publisher "AI Venture Holdings LLC; https://cortexlinux.com" \ - --iso-volume "Cortex Linux ${VERSION}" \ - --memtest none \ - --security true \ - --updates true \ - --backports true \ - --apt-indices true \ - --apt-recommends true \ - --apt-source-archives false \ - --cache true \ - --cache-indices true \ - --cache-packages true \ - --cache-stages true \ - --checksums sha256 \ - --chroot-filesystem squashfs \ - --clean \ - --color \ - --compression xz \ - --debconf-frontend noninteractive \ - --debconf-priority critical \ - --debootstrap-options "--variant=minbase --include=apt-transport-https,ca-certificates,gnupg" \ - --firmware-binary true \ - --firmware-chroot true \ - --hdd-size auto \ - --image-name "cortex-linux" \ - --initramfs live-boot \ - --initramfs-compression xz \ - --initsystem systemd \ - --interactive false \ - --linux-flavours "${ARCH}" \ - --linux-packages "linux-image linux-headers" \ - --mode debian \ - --quiet \ - --system live \ - --verbose \ - --bootappend-live "boot=live components quiet splash locales=en_US.UTF-8 keyboard-layouts=us" \ - "${@}" - -echo "Cortex Linux live-build configured successfully" diff --git a/iso/live-build/config/bootloaders/grub-pc/config.cfg b/iso/live-build/config/bootloaders/grub-pc/config.cfg new file mode 100644 index 0000000..bd05cb5 --- /dev/null +++ b/iso/live-build/config/bootloaders/grub-pc/config.cfg @@ -0,0 +1,30 @@ +set default=0 + +if [ x$feature_default_font_path = xy ] ; then + font=unicode +else + font=$prefix/unicode.pf2 +fi + +# Copied from the netinst image +if loadfont $font ; then + set gfxmode=auto + set gfxpayload=keep + insmod efi_gop + insmod efi_uga + insmod video_bochs + insmod video_cirrus +else + set gfxmode=auto + insmod all_video +fi + +insmod gfxterm +insmod png + +source /boot/grub/theme.cfg + +terminal_output gfxterm + +insmod play +play 960 440 1 0 4 440 1 diff --git a/iso/live-build/config/bootloaders/grub-pc/grub.cfg b/iso/live-build/config/bootloaders/grub-pc/grub.cfg new file mode 100644 index 0000000..e175209 --- /dev/null +++ b/iso/live-build/config/bootloaders/grub-pc/grub.cfg @@ -0,0 +1,57 @@ +source /boot/grub/config.cfg + +# Live boot +@LINUX_LIVE@ + +# You can add more entries like this +# menuentry "Alternate live boot" { +# linux @KERNEL_LIVE@ @APPEND_LIVE@ custom options here +# initrd @INITRD_LIVE@ +# } +# menuentry "Alternate graphical installer" { +# linux @KERNEL_GI@ @APPEND_GI@ custom options here +# initrd @INITRD_GI@ +# } +# menuentry "Alternate textual installer" { +# linux @KERNEL_DI@ @APPEND_DI@ custom options here +# initrd @INITRD_DI@ +# } + +# Installer (if any) +if @ENABLE_INSTALL_MENU@; then + +source /boot/grub/install_start.cfg + +submenu 'Advanced install options ...' --hotkey=a { + + source /boot/grub/theme.cfg + + source /boot/grub/install.cfg + +} +fi + +submenu 'Utilities...' --hotkey=u { + + source /boot/grub/theme.cfg + + # Memtest (if any) + if @ENABLE_MEMTEST@; then + source /boot/grub/memtest.cfg + fi + + # Firmware setup (UEFI) + if [ "${grub_platform}" = "efi" ]; then + menuentry "UEFI Firmware Settings" --hotkey=f { + fwsetup + } + fi + + # Verify the checksums + if @ENABLE_VERIFY_CHECKSUMS@; then + menuentry "Verify integrity of the boot medium" --hotkey=v { + linux @KERNEL_LIVE@ @APPEND_VERIFY_CHECKSUMS@ + initrd @INITRD_LIVE@ + } + fi +} diff --git a/iso/live-build/config/bootloaders/grub-pc/install_gui.cfg b/iso/live-build/config/bootloaders/grub-pc/install_gui.cfg new file mode 100644 index 0000000..61be681 --- /dev/null +++ b/iso/live-build/config/bootloaders/grub-pc/install_gui.cfg @@ -0,0 +1,124 @@ +submenu 'Graphical installer ...' --hotkey=g { + + source /boot/grub/theme.cfg + + menuentry 'Install' --hotkey=i { + linux @KERNEL_GI@ vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ + } + + menuentry 'Expert install' --hotkey=x { + linux @KERNEL_GI@ priority=low vga=788 @APPEND_INSTALL@ + initrd @INITRD_GI@ + } + + menuentry 'Automated install' --hotkey=a { + linux @KERNEL_GI@ auto=true priority=critical vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ + } + + menuentry 'Rescue mode' --hotkey=r { + linux @KERNEL_GI@ rescue/enable=true vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ + } +} + +submenu 'Text installer ...' --hotkey=t { + + source /boot/grub/theme.cfg + + menuentry 'Install' --hotkey=i { + linux @KERNEL_DI@ vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } + + menuentry 'Expert install' --hotkey=x { + linux @KERNEL_DI@ priority=low vga=788 @APPEND_INSTALL@ + initrd @INITRD_DI@ + } + + menuentry 'Automated install' --hotkey=a { + linux @KERNEL_DI@ auto=true priority=critical vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } + + menuentry 'Rescue mode' --hotkey=r { + linux @KERNEL_DI@ rescue/enable=true vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } +} + +submenu 'Graphical installer with dark theme ...' --hotkey=d { + + source /boot/grub/theme.cfg + + menuentry 'Install' --hotkey=i { + linux @KERNEL_GI@ vga=788 theme=dark @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ + } + + menuentry 'Expert install' --hotkey=x { + linux @KERNEL_GI@ priority=low vga=788 theme=dark @APPEND_INSTALL@ + initrd @INITRD_GI@ + } + + menuentry 'Automated install' --hotkey=a { + linux @KERNEL_GI@ auto=true priority=critical vga=788 theme=dark @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ + } + + menuentry 'Rescue mode' --hotkey=r { + linux @KERNEL_GI@ rescue/enable=true vga=788 theme=dark @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ + } +} + +submenu 'Text installer with dark theme ...' --hotkey=k { + + source /boot/grub/theme.cfg + + menuentry 'Install' --hotkey=i { + linux @KERNEL_DI@ vga=788 theme=dark @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } + + menuentry 'Expert install' --hotkey=x { + linux @KERNEL_DI@ priority=low vga=788 theme=dark @APPEND_INSTALL@ + initrd @INITRD_DI@ + } + + menuentry 'Automated install' --hotkey=a { + linux @KERNEL_DI@ auto=true priority=critical vga=788 theme=dark @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } + + menuentry 'Rescue mode' --hotkey=r { + linux @KERNEL_DI@ rescue/enable=true vga=788 theme=dark @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } +} + +submenu 'Installer with speech synthesis ...' --hotkey=s { + + source /boot/grub/theme.cfg + + menuentry 'Install' --hotkey=i { + linux @KERNEL_GI@ speakup.synth=soft vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ + } + + menuentry 'Expert install' --hotkey=x { + linux @KERNEL_GI@ speakup.synth=soft priority=low vga=788 @APPEND_INSTALL@ + initrd @INITRD_GI@ + } + + menuentry 'Automated install' --hotkey=a { + linux @KERNEL_GI@ speakup.synth=soft auto=true priority=critical vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ + } + + menuentry 'Rescue mode' --hotkey=r { + linux @KERNEL_GI@ speakup.synth=soft rescue/enable=true vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ + } +} diff --git a/iso/live-build/config/bootloaders/grub-pc/install_start_gui.cfg b/iso/live-build/config/bootloaders/grub-pc/install_start_gui.cfg new file mode 100644 index 0000000..92dde17 --- /dev/null +++ b/iso/live-build/config/bootloaders/grub-pc/install_start_gui.cfg @@ -0,0 +1,9 @@ +menuentry 'Start installer' --hotkey=i { + linux @KERNEL_GI@ vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ +} + +menuentry 'Start installer with speech synthesis' --hotkey=s { + linux @KERNEL_GI@ speakup.synth=soft vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_GI@ +} diff --git a/iso/live-build/config/bootloaders/grub-pc/install_start_text.cfg b/iso/live-build/config/bootloaders/grub-pc/install_start_text.cfg new file mode 100644 index 0000000..33da222 --- /dev/null +++ b/iso/live-build/config/bootloaders/grub-pc/install_start_text.cfg @@ -0,0 +1,4 @@ +menuentry 'Start installer' --hotkey=i { + linux @KERNEL_DI@ vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ +} diff --git a/iso/live-build/config/bootloaders/grub-pc/install_text.cfg b/iso/live-build/config/bootloaders/grub-pc/install_text.cfg new file mode 100644 index 0000000..dc6b222 --- /dev/null +++ b/iso/live-build/config/bootloaders/grub-pc/install_text.cfg @@ -0,0 +1,49 @@ +submenu 'Text installer ...' --hotkey=t { + + source /boot/grub/theme.cfg + + menuentry 'Install' --hotkey=i { + linux @KERNEL_DI@ vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } + + menuentry 'Expert install' --hotkey=x { + linux @KERNEL_DI@ priority=low vga=788 @APPEND_INSTALL@ + initrd @INITRD_DI@ + } + + menuentry 'Automated install' --hotkey=a { + linux @KERNEL_DI@ auto=true priority=critical vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } + + menuentry 'Rescue mode' --hotkey=r { + linux @KERNEL_DI@ rescue/enable=true vga=788 @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } +} + +submenu 'Text installer with dark theme ...' --hotkey=k { + + source /boot/grub/theme.cfg + + menuentry 'Install' --hotkey=i { + linux @KERNEL_DI@ vga=788 theme=dark @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } + + menuentry 'Expert install' --hotkey=x { + linux @KERNEL_DI@ priority=low vga=788 theme=dark @APPEND_INSTALL@ + initrd @INITRD_DI@ + } + + menuentry 'Automated install' --hotkey=a { + linux @KERNEL_DI@ auto=true priority=critical vga=788 theme=dark @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } + + menuentry 'Rescue mode' --hotkey=r { + linux @KERNEL_DI@ rescue/enable=true vga=788 theme=dark @APPEND_INSTALL@ --- quiet + initrd @INITRD_DI@ + } +} diff --git a/iso/live-build/config/bootloaders/grub-pc/memtest.cfg b/iso/live-build/config/bootloaders/grub-pc/memtest.cfg new file mode 100644 index 0000000..48697a5 --- /dev/null +++ b/iso/live-build/config/bootloaders/grub-pc/memtest.cfg @@ -0,0 +1,14 @@ +if [ "${grub_platform}" = "pc" ] -a [ -e @MEMTEST_DIR@/memtest ]; then + # Legacy 16-bit memtest + menuentry "Memory Diagnostic Tool (@MEMTEST_VERSION@)" --hotkey=m { + linux16 @MEMTEST_DIR@/memtest + } +elif [ "${grub_platform}" = "pc" ] -a [ -e @MEMTEST_DIR@/memtest.bin ]; then + menuentry "Memory Diagnostic Tool (@MEMTEST_VERSION@)" --hotkey=m { + linux @MEMTEST_DIR@/memtest.bin + } +elif [ "${grub_platform}" = "efi" ] -a [ -e @MEMTEST_DIR@/memtest.efi ]; then + menuentry "Memory Diagnostic Tool (@MEMTEST_VERSION@)" --hotkey=m { + linux @MEMTEST_DIR@/memtest.efi + } +fi diff --git a/iso/live-build/config/bootloaders/grub-pc/splash.png b/iso/live-build/config/bootloaders/grub-pc/splash.png new file mode 100644 index 0000000..87c7def Binary files /dev/null and b/iso/live-build/config/bootloaders/grub-pc/splash.png differ diff --git a/iso/live-build/config/bootloaders/grub-pc/theme.cfg b/iso/live-build/config/bootloaders/grub-pc/theme.cfg new file mode 100644 index 0000000..32ea95a --- /dev/null +++ b/iso/live-build/config/bootloaders/grub-pc/theme.cfg @@ -0,0 +1,8 @@ +# Cortex Linux GRUB Theme Configuration +set color_normal=light-gray/black +set color_highlight=cyan/black + +# Always load Cortex theme +set theme=/boot/grub/live-theme/theme.txt +set menu_color_normal=light-gray/black +set menu_color_highlight=cyan/black diff --git a/iso/live-build/config/hooks/live/0100-cortex-config.hook.chroot b/iso/live-build/config/hooks/live/0100-cortex-config.hook.chroot index afe423c..f4b204d 100755 --- a/iso/live-build/config/hooks/live/0100-cortex-config.hook.chroot +++ b/iso/live-build/config/hooks/live/0100-cortex-config.hook.chroot @@ -130,37 +130,47 @@ EOF # SYSTEMD SERVICES # ============================================================================= -# Cortex first-boot service -cat > /etc/systemd/system/cortex-firstboot.service << 'EOF' +# Cortex first-boot service (canonical version from iso/provisioning/) +# Note: The actual first-boot.sh is deployed via preseed to /opt/cortex/provisioning/ +cat > /etc/systemd/system/cortex-first-boot.service << 'EOF' [Unit] -Description=Cortex Linux First Boot Provisioning -After=network-online.target -Wants=network-online.target -ConditionPathExists=!/etc/cortex/.firstboot-complete +Description=Cortex Linux First-Boot Provisioning +Documentation=https://github.com/cortexlinux/cortex-distro +After=network-pre.target systemd-resolved.service +Before=network.target getty@tty1.service display-manager.service +Wants=network-pre.target +ConditionPathExists=!/opt/cortex/provisioning/.first-boot-complete [Service] Type=oneshot -ExecStart=/usr/lib/cortex/firstboot.sh -ExecStartPost=/usr/bin/touch /etc/cortex/.firstboot-complete +ExecStart=/opt/cortex/provisioning/first-boot.sh RemainAfterExit=yes +TimeoutSec=600 +NoNewPrivileges=false +ProtectSystem=false +ProtectHome=false +PrivateTmp=true StandardOutput=journal+console StandardError=journal+console +SyslogIdentifier=cortex-first-boot [Install] WantedBy=multi-user.target EOF # Enable first-boot service -systemctl enable cortex-firstboot.service +systemctl enable cortex-first-boot.service # ============================================================================= # SECURITY HARDENING # ============================================================================= -# Disable unnecessary services -systemctl disable bluetooth.service 2>/dev/null || true -systemctl disable cups.service 2>/dev/null || true -systemctl disable avahi-daemon.service 2>/dev/null || true +# Disable unnecessary services (only if installed) +for svc in bluetooth.service cups.service avahi-daemon.service; do + if systemctl list-unit-files "$svc" &>/dev/null; then + systemctl disable "$svc" + fi +done # Kernel security parameters cat > /etc/sysctl.d/99-cortex-security.conf << 'EOF' diff --git a/iso/live-build/config/hooks/live/50-cortex-branding.hook.chroot b/iso/live-build/config/hooks/live/50-cortex-branding.hook.chroot new file mode 100755 index 0000000..f10198b --- /dev/null +++ b/iso/live-build/config/hooks/live/50-cortex-branding.hook.chroot @@ -0,0 +1,94 @@ +#!/bin/bash +# +# Cortex Linux Branding - Build Verification Hook +# +# This hook runs AFTER cortex-branding package is installed (via packages.chroot). +# It only verifies that the package was installed correctly during ISO build. +# +# All branding configuration is handled by the cortex-branding package's postinst: +# - Plymouth theme registration and configuration +# - GRUB theme and distributor settings +# - MOTD script permissions +# - GDM/dconf branding +# - Neofetch configuration +# + +set -e + +echo "================================================" +echo " Cortex Linux Branding Verification" +echo "================================================" + +# ============================================================================ +# Verify cortex-branding package was installed +# ============================================================================ + +echo " -> Verifying cortex-branding package installation..." + +MISSING=0 +check_file() { + if [ ! -f "$1" ]; then + echo " WARNING: Missing $1" + MISSING=$((MISSING + 1)) + fi +} + +# Core branding files +check_file "/etc/os-release" +check_file "/etc/lsb-release" + +# Plymouth theme +check_file "/usr/share/plymouth/themes/cortex/cortex.plymouth" + +# GRUB theme +check_file "/boot/grub/themes/cortex/theme.txt" + +# Wallpapers +check_file "/usr/share/backgrounds/cortex/minimal-dark.png" + +# MOTD +check_file "/etc/update-motd.d/00-cortex-banner" + +# Neofetch +check_file "/etc/neofetch/config.conf" + +# dconf settings +check_file "/etc/dconf/db/local.d/00-cortex-desktop" +check_file "/etc/dconf/db/local.d/01-cortex-terminal" +check_file "/etc/dconf/profile/user" + +# GSettings override +check_file "/usr/share/glib-2.0/schemas/10-cortex-branding.gschema.override" + +# GDM theme +check_file "/usr/share/gnome-shell/theme/Cortex/gnome-shell.css" +check_file "/usr/share/cortex/logos/cortex-logo-light.svg" + +if [ $MISSING -gt 0 ]; then + echo "" + echo " ⚠ WARNING: $MISSING expected files missing!" + echo " Make sure cortex-branding.deb is in config/packages.chroot/" + echo " Run: make branding-package && cp output/*.deb iso/live-build/config/packages.chroot/" + echo "" +else + echo " ✓ All branding files verified successfully" +fi + +# ============================================================================ +# Verify Plymouth theme is active +# ============================================================================ + +echo " -> Checking Plymouth theme..." + +if command -v plymouth-set-default-theme &>/dev/null; then + THEME=$(plymouth-set-default-theme 2>/dev/null || echo "unknown") + if [ "$THEME" = "cortex" ]; then + echo " ✓ Plymouth theme: $THEME" + else + echo " ⚠ Plymouth theme is '$THEME', expected 'cortex'" + fi +fi + +echo "================================================" +echo " Branding Verification Complete" +echo "================================================" diff --git a/iso/live-build/config/hooks/live/99-live-session.hook.chroot b/iso/live-build/config/hooks/live/99-live-session.hook.chroot new file mode 100755 index 0000000..472b567 --- /dev/null +++ b/iso/live-build/config/hooks/live/99-live-session.hook.chroot @@ -0,0 +1,96 @@ +#!/bin/bash +# +# Cortex Linux Live Session Configuration Hook +# +# This hook configures LIVE-SPECIFIC settings only. +# All branding (themes, wallpapers, terminal) is handled by the cortex-branding package. +# +# Live-specific settings: +# - Live user creation (cortex:cortex) +# - GDM autologin for live session +# - Welcome script +# - Graphical target +# + +set -e + +# Ensure /usr/sbin is in PATH for initramfs tools +export PATH="$PATH:/usr/sbin" + +echo "Configuring Cortex Linux live session..." + +# ============================================================================ +# Live User Configuration +# ============================================================================ + +mkdir -p /etc/live/config.conf.d + +cat > /etc/live/config.conf.d/cortex-live.conf << 'EOF' +# Cortex Linux Live Session Configuration +LIVE_USER_DEFAULT=cortex +LIVE_HOSTNAME=cortex-live +LIVE_USERNAME=cortex +LIVE_USER_FULLNAME="Cortex Live User" +LIVE_USER_PASSWORD="cortex" +EOF + +# ============================================================================ +# GDM Autologin for Live Session +# ============================================================================ + +mkdir -p /etc/gdm3 +cat > /etc/gdm3/daemon.conf << 'EOF' +# Cortex Linux GDM Configuration for Live Environment +[daemon] +AutomaticLoginEnable=true +AutomaticLogin=cortex +EOF + +cat > /etc/gdm3/custom.conf << 'EOF' +# Cortex Linux GDM Custom Configuration +[daemon] +AutomaticLoginEnable=true +AutomaticLogin=cortex +EOF + +# ============================================================================ +# Ensure Graphical Target +# ============================================================================ + +systemctl set-default graphical.target + +# ============================================================================ +# Create Skeleton Directories for Live User +# ============================================================================ + +mkdir -p /etc/skel/Desktop +mkdir -p /etc/skel/Documents +mkdir -p /etc/skel/Downloads +mkdir -p /etc/skel/Pictures +mkdir -p /etc/skel/.config/autostart + +# ============================================================================ +# Live Welcome Script +# ============================================================================ + +cat > /etc/skel/.config/autostart/welcome.desktop << 'EOF' +[Desktop Entry] +Type=Application +Name=Welcome to Cortex Linux +Exec=gnome-terminal -- bash -c "echo 'Welcome to Cortex Linux Live!'; echo 'Desktop environment: GNOME'; echo 'Username: cortex'; echo 'Password: cortex'; echo ''; echo 'Press Enter to continue...'; read" +Terminal=false +StartupNotify=false +X-GNOME-Autostart-enabled=true +EOF + +chmod +x /etc/skel/.config/autostart/welcome.desktop + +# ============================================================================ +# Update dconf database (branding files installed by cortex-branding package) +# ============================================================================ + +if command -v dconf &>/dev/null; then + dconf update +fi + +echo "Live session configuration complete." diff --git a/iso/live-build/config/includes.chroot/etc/pam.d/login b/iso/live-build/config/includes.chroot/etc/pam.d/login new file mode 100644 index 0000000..5b4482a --- /dev/null +++ b/iso/live-build/config/includes.chroot/etc/pam.d/login @@ -0,0 +1,16 @@ +# PAM configuration for login service +# Cortex Linux - enables MOTD display on console login + +auth optional pam_faildelay.so delay=3000000 +auth requisite pam_nologin.so +auth include common-auth +account required pam_nologin.so +account include common-account +password include common-password +session required pam_loginuid.so +session optional pam_keyinit.so force revoke +session include common-session +session optional pam_motd.so motd=/run/motd.dynamic +session optional pam_motd.so noupdate +session optional pam_mail.so standard +session required pam_env.so user_readenv=1 envfile=/etc/default/locale diff --git a/iso/live-build/config/includes.chroot/etc/pam.d/sshd b/iso/live-build/config/includes.chroot/etc/pam.d/sshd new file mode 100644 index 0000000..e242e0a --- /dev/null +++ b/iso/live-build/config/includes.chroot/etc/pam.d/sshd @@ -0,0 +1,15 @@ +# PAM configuration for sshd service +# Cortex Linux - enables MOTD display on SSH login + +@include common-auth +account required pam_nologin.so +@include common-account +session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close +session required pam_loginuid.so +session optional pam_keyinit.so force revoke +@include common-session +session optional pam_motd.so motd=/run/motd.dynamic +session optional pam_motd.so noupdate +session optional pam_mail.so standard noenv +session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open +@include common-password diff --git a/iso/live-build/config/includes.chroot/etc/skel/.bashrc b/iso/live-build/config/includes.chroot/etc/skel/.bashrc new file mode 100644 index 0000000..c61fcb4 --- /dev/null +++ b/iso/live-build/config/includes.chroot/etc/skel/.bashrc @@ -0,0 +1,181 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# Cortex Linux - AI-Powered Linux Distribution + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return;; +esac + +# ============================================================================= +# HISTORY CONFIGURATION +# ============================================================================= +HISTCONTROL=ignoreboth +HISTSIZE=10000 +HISTFILESIZE=20000 +shopt -s histappend + +# ============================================================================= +# SHELL OPTIONS +# ============================================================================= +shopt -s checkwinsize +shopt -s globstar 2>/dev/null +shopt -s cdspell 2>/dev/null +shopt -s dirspell 2>/dev/null + +# ============================================================================= +# CORTEX BRANDED PROMPT (PS1) +# ============================================================================= +# Colors +PURPLE='\[\033[0;35m\]' +CYAN='\[\033[0;36m\]' +WHITE='\[\033[1;37m\]' +GRAY='\[\033[0;90m\]' +GREEN='\[\033[0;32m\]' +YELLOW='\[\033[0;33m\]' +RED='\[\033[0;31m\]' +RESET='\[\033[0m\]' +BOLD='\[\033[1m\]' + +# Git branch function +__git_branch() { + git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \1/' +} + +# Git status indicators +__git_status() { + local status="" + local git_status=$(git status --porcelain 2>/dev/null) + if [[ -n "$git_status" ]]; then + if echo "$git_status" | grep -q "^??"; then + status+="?" + fi + if echo "$git_status" | grep -q "^.M\|^M"; then + status+="*" + fi + if echo "$git_status" | grep -q "^A\|^.A"; then + status+="+" + fi + fi + [[ -n "$status" ]] && echo " $status" +} + +# Build the prompt +__cortex_prompt() { + local exit_code=$? + local prompt="" + + # Show exit code if non-zero + if [[ $exit_code -ne 0 ]]; then + prompt+="${RED}[$exit_code]${RESET} " + fi + + # User@host (purple for root, cyan for user) + if [[ $EUID -eq 0 ]]; then + prompt+="${RED}${BOLD}\u${RESET}" + else + prompt+="${PURPLE}${BOLD}\u${RESET}" + fi + + prompt+="${GRAY}@${RESET}" + prompt+="${CYAN}\h${RESET}" + + # Current directory + prompt+=" ${WHITE}\w${RESET}" + + # Git info if in a repo + if git rev-parse --is-inside-work-tree &>/dev/null 2>&1; then + prompt+="${PURPLE}$(__git_branch)${YELLOW}$(__git_status)${RESET}" + fi + + # Prompt symbol (# for root, ❯ for user) + if [[ $EUID -eq 0 ]]; then + prompt+="\n${RED}#${RESET} " + else + prompt+="\n${CYAN}❯${RESET} " + fi + + PS1="$prompt" +} + +PROMPT_COMMAND=__cortex_prompt + +# ============================================================================= +# COLORS FOR LS AND GREP +# ============================================================================= +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + alias dir='dir --color=auto' + alias vdir='vdir --color=auto' + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# ============================================================================= +# USEFUL ALIASES +# ============================================================================= +# Navigation +alias ..='cd ..' +alias ...='cd ../..' +alias ....='cd ../../..' + +# Listing +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' +alias lt='ls -ltrh' + +# Safety +alias rm='rm -i' +alias cp='cp -i' +alias mv='mv -i' + +# System +alias df='df -h' +alias du='du -h' +alias free='free -h' +alias top='htop 2>/dev/null || top' + +# Cortex specific +alias sysinfo='neofetch' +alias update='sudo apt update && sudo apt upgrade' +alias cleanup='sudo apt autoremove && sudo apt autoclean' + +# ============================================================================= +# COMPLETION +# ============================================================================= +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi + +# ============================================================================= +# WELCOME MESSAGE (neofetch on first terminal) +# ============================================================================= +# Only show neofetch on first interactive shell (not in subshells or scripts) +if [[ -z "$CORTEX_WELCOMED" ]] && command -v neofetch &>/dev/null; then + export CORTEX_WELCOMED=1 + neofetch +fi + +# ============================================================================= +# PATH ADDITIONS +# ============================================================================= +# Add user's private bin if it exists +if [ -d "$HOME/.local/bin" ]; then + PATH="$HOME/.local/bin:$PATH" +fi + +if [ -d "$HOME/bin" ]; then + PATH="$HOME/bin:$PATH" +fi + +# Cortex tools +if [ -d "/opt/cortex/bin" ]; then + PATH="/opt/cortex/bin:$PATH" +fi diff --git a/iso/live-build/config/includes.chroot/usr/lib/cortex/firstboot.sh b/iso/live-build/config/includes.chroot/usr/lib/cortex/firstboot.sh deleted file mode 100755 index 20aacc0..0000000 --- a/iso/live-build/config/includes.chroot/usr/lib/cortex/firstboot.sh +++ /dev/null @@ -1,369 +0,0 @@ -#!/bin/bash -# Cortex Linux First Boot Provisioning -# Runs on first boot to complete system setup -# Copyright 2025 AI Venture Holdings LLC -# SPDX-License-Identifier: Apache-2.0 - -set -e - -PROVISION_VERSION="1.0.0" -PROVISION_LOG="/var/log/cortex/firstboot.log" -STATE_FILE="/etc/cortex/.provision-state" -CONFIG_FILE="/etc/cortex/provision.yaml" - -# Logging -log() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$PROVISION_LOG" -} - -log_section() { - log "==============================================" - log "$*" - log "==============================================" -} - -# Error handling -error_exit() { - log "ERROR: $*" - exit 1 -} - -# State management for idempotency -state_get() { - local key="$1" - if [ -f "$STATE_FILE" ]; then - grep "^${key}=" "$STATE_FILE" 2>/dev/null | cut -d'=' -f2- - fi -} - -state_set() { - local key="$1" - local value="$2" - mkdir -p "$(dirname "$STATE_FILE")" - if [ -f "$STATE_FILE" ]; then - sed -i "/^${key}=/d" "$STATE_FILE" - fi - echo "${key}=${value}" >> "$STATE_FILE" -} - -state_done() { - local step="$1" - state_set "step_${step}" "done" -} - -state_check() { - local step="$1" - [ "$(state_get "step_${step}")" = "done" ] -} - -# ============================================================================= -# PROVISIONING STEPS -# ============================================================================= - -provision_hostname() { - if state_check "hostname"; then - log "Hostname already configured, skipping" - return 0 - fi - - log_section "Configuring Hostname" - - # Read from provision config or use default - local hostname="${CORTEX_HOSTNAME:-cortex}" - - if [ -f "$CONFIG_FILE" ]; then - local cfg_hostname - cfg_hostname=$(grep -E "^hostname:" "$CONFIG_FILE" 2>/dev/null | awk '{print $2}') - [ -n "$cfg_hostname" ] && hostname="$cfg_hostname" - fi - - hostnamectl set-hostname "$hostname" - log "Hostname set to: $hostname" - - state_done "hostname" -} - -provision_network() { - if state_check "network"; then - log "Network already configured, skipping" - return 0 - fi - - log_section "Configuring Network" - - # Network is typically configured via DHCP during install - # This step validates connectivity - - if ping -c 1 -W 5 8.8.8.8 &>/dev/null; then - log "Network connectivity verified" - else - log "WARNING: No network connectivity detected" - log "System will operate in offline mode" - fi - - state_done "network" -} - -provision_timezone() { - if state_check "timezone"; then - log "Timezone already configured, skipping" - return 0 - fi - - log_section "Configuring Timezone" - - local timezone="${CORTEX_TIMEZONE:-UTC}" - - if [ -f "$CONFIG_FILE" ]; then - local cfg_tz - cfg_tz=$(grep -E "^timezone:" "$CONFIG_FILE" 2>/dev/null | awk '{print $2}') - [ -n "$cfg_tz" ] && timezone="$cfg_tz" - fi - - timedatectl set-timezone "$timezone" - log "Timezone set to: $timezone" - - state_done "timezone" -} - -provision_ssh() { - if state_check "ssh"; then - log "SSH already configured, skipping" - return 0 - fi - - log_section "Configuring SSH" - - # Ensure SSH is enabled - systemctl enable ssh - systemctl start ssh - - # Generate host keys if missing - if [ ! -f /etc/ssh/ssh_host_ed25519_key ]; then - log "Regenerating SSH host keys..." - rm -f /etc/ssh/ssh_host_* - dpkg-reconfigure openssh-server - fi - - # Inject authorized keys if provided - if [ -f "$CONFIG_FILE" ]; then - local ssh_keys - ssh_keys=$(grep -E "^ssh_authorized_keys:" -A 100 "$CONFIG_FILE" 2>/dev/null | grep -E "^\s+-" | sed 's/^\s*-\s*//') - - if [ -n "$ssh_keys" ]; then - local admin_user - admin_user=$(grep -E "^admin_user:" "$CONFIG_FILE" | awk '{print $2}') - admin_user="${admin_user:-cortex}" - - local ssh_dir="/home/${admin_user}/.ssh" - mkdir -p "$ssh_dir" - echo "$ssh_keys" >> "${ssh_dir}/authorized_keys" - chmod 700 "$ssh_dir" - chmod 600 "${ssh_dir}/authorized_keys" - chown -R "${admin_user}:${admin_user}" "$ssh_dir" - - log "SSH keys installed for user: $admin_user" - - # Disable password auth if keys provided - sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config.d/cortex.conf - systemctl reload ssh - log "Password authentication disabled (SSH keys configured)" - fi - fi - - log "SSH configured and running" - state_done "ssh" -} - -provision_admin_user() { - if state_check "admin_user"; then - log "Admin user already configured, skipping" - return 0 - fi - - log_section "Configuring Admin User" - - local admin_user="${CORTEX_ADMIN_USER:-cortex}" - - if [ -f "$CONFIG_FILE" ]; then - local cfg_user - cfg_user=$(grep -E "^admin_user:" "$CONFIG_FILE" 2>/dev/null | awk '{print $2}') - [ -n "$cfg_user" ] && admin_user="$cfg_user" - fi - - # Create user if doesn't exist - if ! id "$admin_user" &>/dev/null; then - useradd -m -s /bin/bash -G sudo,docker "$admin_user" - log "Created admin user: $admin_user" - fi - - # Ensure sudo access - echo "${admin_user} ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/${admin_user}" - chmod 440 "/etc/sudoers.d/${admin_user}" - - log "Admin user configured: $admin_user" - state_done "admin_user" -} - -provision_apt_repos() { - if state_check "apt_repos"; then - log "APT repositories already configured, skipping" - return 0 - fi - - log_section "Configuring APT Repositories" - - # Update package lists - apt-get update || log "WARNING: apt-get update failed (offline mode?)" - - log "APT repositories configured" - state_done "apt_repos" -} - -provision_cortex() { - if state_check "cortex"; then - log "Cortex already installed, skipping" - return 0 - fi - - log_section "Installing Cortex" - - # Check if we have network for installation - if ping -c 1 -W 5 repo.cortexlinux.com &>/dev/null; then - apt-get install -y cortex-core || log "WARNING: cortex-core installation failed" - else - log "No network access to Cortex repository" - log "Cortex will be installed from local packages if available" - - # Check for local packages - if ls /var/cache/cortex/*.deb &>/dev/null; then - dpkg -i /var/cache/cortex/*.deb || true - apt-get install -f -y - fi - fi - - state_done "cortex" -} - -provision_security() { - if state_check "security"; then - log "Security baseline already applied, skipping" - return 0 - fi - - log_section "Applying Security Baseline" - - # Apply sysctl settings - sysctl --system - - # Enable AppArmor - if command -v aa-status &>/dev/null; then - systemctl enable apparmor - systemctl start apparmor - log "AppArmor enabled" - fi - - # Configure firewall (nftables) - if command -v nft &>/dev/null; then - cat > /etc/nftables.conf << 'EOF' -#!/usr/sbin/nft -f - -flush ruleset - -table inet filter { - chain input { - type filter hook input priority 0; policy drop; - - # Allow established connections - ct state established,related accept - - # Allow loopback - iif lo accept - - # Allow SSH - tcp dport 22 accept - - # Allow Cortex web console (when enabled) - tcp dport 8006 accept - - # Allow ICMP - icmp type echo-request accept - icmpv6 type echo-request accept - - # Drop invalid - ct state invalid drop - } - - chain forward { - type filter hook forward priority 0; policy drop; - } - - chain output { - type filter hook output priority 0; policy accept; - } -} -EOF - systemctl enable nftables - systemctl start nftables - log "Firewall configured (nftables)" - fi - - log "Security baseline applied" - state_done "security" -} - -provision_webconsole() { - if state_check "webconsole"; then - log "Web console already configured, skipping" - return 0 - fi - - log_section "Configuring Web Console" - - # Web console will be configured when cortex-console is installed - # This step prepares the environment - - mkdir -p /etc/cortex/console - mkdir -p /var/lib/cortex/console - - log "Web console environment prepared" - log "Install cortex-console to enable web management on port 8006" - - state_done "webconsole" -} - -# ============================================================================= -# MAIN -# ============================================================================= - -main() { - log_section "Cortex Linux First Boot Provisioning v${PROVISION_VERSION}" - log "Started: $(date)" - - # Create log directory - mkdir -p "$(dirname "$PROVISION_LOG")" - - # Run provisioning steps in order - provision_hostname - provision_network - provision_timezone - provision_ssh - provision_admin_user - provision_apt_repos - provision_cortex - provision_security - provision_webconsole - - # Mark provisioning complete - state_set "provision_version" "$PROVISION_VERSION" - state_set "provision_complete" "$(date -Iseconds)" - - log_section "Provisioning Complete" - log "Finished: $(date)" - log "" - log "System is ready. Connect via SSH or web console (port 8006)" - log "" -} - -# Run main function -main "$@" diff --git a/iso/live-build/config/package-lists/cortex-core.list.chroot b/iso/live-build/config/package-lists/cortex-core.list.chroot deleted file mode 100644 index 31e6a4c..0000000 --- a/iso/live-build/config/package-lists/cortex-core.list.chroot +++ /dev/null @@ -1,113 +0,0 @@ -# Cortex Linux Core Package List -# Minimal server installation with Cortex AI package manager -# Copyright 2025 AI Venture Holdings LLC -# SPDX-License-Identifier: Apache-2.0 - -# ============================================================================= -# SYSTEM BASE -# ============================================================================= -# Essential system utilities -systemd -systemd-sysv -dbus -udev -init - -# Core utilities -coreutils -util-linux -procps -psmisc -lsof -strace -file -less -vim-tiny -nano - -# Networking base -iproute2 -iputils-ping -netbase -netcat-openbsd -curl -wget -openssh-server -openssh-client - -# System management -sudo -acl -apt-transport-https -ca-certificates -gnupg -gpg-agent - -# Hardware detection -pciutils -usbutils -dmidecode -hwinfo -lshw - -# Filesystem -e2fsprogs -xfsprogs -btrfs-progs -lvm2 -mdadm -parted -gdisk -cryptsetup - -# Compression -xz-utils -bzip2 -gzip -zstd -unzip -zip - -# ============================================================================= -# CORTEX REQUIREMENTS -# ============================================================================= -# Python runtime (Cortex core dependency) -python3 -python3-pip -python3-venv -python3-dev - -# Build essentials for Python packages -build-essential -gcc -g++ -make - -# JSON/YAML processing -jq -python3-yaml - -# Security sandbox -firejail -apparmor -apparmor-utils - -# Logging and monitoring -rsyslog -logrotate - -# ============================================================================= -# FIRMWARE & DRIVERS -# ============================================================================= -# Essential firmware -firmware-linux-free -firmware-misc-nonfree -amd64-microcode -intel-microcode - -# ============================================================================= -# CORTEX PACKAGES (from Cortex repository) -# ============================================================================= -# These will be installed from the Cortex APT repository -# cortex-archive-keyring -# cortex-core diff --git a/iso/live-build/config/package-lists/cortex-full.list.chroot b/iso/live-build/config/package-lists/cortex.list.chroot similarity index 68% rename from iso/live-build/config/package-lists/cortex-full.list.chroot rename to iso/live-build/config/package-lists/cortex.list.chroot index 6bd9556..cd0bc7f 100644 --- a/iso/live-build/config/package-lists/cortex-full.list.chroot +++ b/iso/live-build/config/package-lists/cortex.list.chroot @@ -1,12 +1,107 @@ -# Cortex Linux Full Package List -# Full server installation with GPU support and extended tooling +# Cortex Linux Package List +# Complete system installation with GPU support, containers, and AI/ML tools # Copyright 2025 AI Venture Holdings LLC # SPDX-License-Identifier: Apache-2.0 # ============================================================================= -# INCLUDE CORE +# SYSTEM BASE # ============================================================================= -# All packages from cortex-core.list.chroot are included via live-build +# Essential system utilities +systemd +systemd-sysv +dbus +udev +init + +# Core utilities +coreutils +util-linux +procps +psmisc +lsof +strace +file +less +vim-tiny +nano + +# Networking base +iproute2 +iputils-ping +netbase +netcat-openbsd +curl +wget +openssh-server +openssh-client + +# System management +sudo +acl +apt-transport-https +ca-certificates +gnupg +gpg-agent + +# Hardware detection +pciutils +usbutils +dmidecode +hwinfo +lshw + +# Filesystem +e2fsprogs +xfsprogs +btrfs-progs +lvm2 +mdadm +parted +gdisk +cryptsetup + +# Compression +xz-utils +bzip2 +gzip +zstd +unzip +zip + +# ============================================================================= +# CORTEX REQUIREMENTS +# ============================================================================= +# Python runtime (Cortex core dependency) +python3 +python3-pip +python3-venv +python3-dev + +# Build essentials for Python packages +build-essential +gcc +g++ +make + +# JSON/YAML processing +jq +python3-yaml + +# Security sandbox +firejail +apparmor +apparmor-utils + +# Logging and monitoring +rsyslog +logrotate + +# ============================================================================= +# FIRMWARE & DRIVERS +# ============================================================================= +# Essential firmware +firmware-linux-free +firmware-misc-nonfree # ============================================================================= # EXTENDED NETWORKING @@ -80,7 +175,6 @@ python3-scipy python3-pandas # Local LLM support (Ollama installed separately) -# These support local inference libopenblas0 libblas3 liblapack3 @@ -94,6 +188,7 @@ tmux screen htop btop +neofetch iotop iftop ncdu @@ -136,7 +231,9 @@ auditd audispd-plugins # ============================================================================= -# CORTEX FULL PACKAGES (from Cortex repository) +# CORTEX PACKAGES (from Cortex repository) # ============================================================================= -# cortex-full +# These will be installed from the Cortex APT repository when available +# cortex-archive-keyring +# cortex-core # cortex-console diff --git a/iso/live-build/config/package-lists/live.list.chroot b/iso/live-build/config/package-lists/live.list.chroot new file mode 100644 index 0000000..0388ddb --- /dev/null +++ b/iso/live-build/config/package-lists/live.list.chroot @@ -0,0 +1,42 @@ +# Cortex Linux Live Environment Package List +# This file specifies packages to include in the live system chroot +# GNOME Desktop Environment and essential components + +# Core desktop packages +task-gnome-desktop +gnome-session +gnome-shell +gdm3 + +# Essential GNOME applications +nautilus +gnome-terminal +gnome-control-center +gnome-settings-daemon + +# System utilities for live environment +network-manager-gnome +pavucontrol +curl +ca-certificates +gnupg + +# Basic applications +firefox-esr +gedit +evince + +# Additional desktop integration +fonts-liberation +fonts-dejavu + +# Live system utilities +live-config +live-boot +live-boot-doc +initramfs-tools + +# Branding and boot splash +plymouth +plymouth-themes +neofetch diff --git a/iso/live-build/config/packages.chroot/.gitkeep b/iso/live-build/config/packages.chroot/.gitkeep new file mode 100644 index 0000000..d075ff4 --- /dev/null +++ b/iso/live-build/config/packages.chroot/.gitkeep @@ -0,0 +1,15 @@ +# Local .deb packages placed here are automatically installed during ISO build +# +# Usage: +# 1. Build packages: make branding-package +# 2. Copy to here: cp output/*.deb iso/live-build/config/packages.chroot/ +# 3. Build ISO: make iso +# +# Packages in this directory: +# - cortex-branding_*.deb - Branding, Plymouth, GRUB theme, wallpapers +# - cortex-core_*.deb - Core tools (when built) +# - etc. +# +# Note: These packages are installed via dpkg, not apt, so dependencies +# must be satisfied by packages in package-lists/*.list.chroot + diff --git a/iso/preseed/partitioning/fde-uefi.preseed b/iso/preseed/partitioning/fde-uefi.preseed new file mode 100644 index 0000000..7886662 --- /dev/null +++ b/iso/preseed/partitioning/fde-uefi.preseed @@ -0,0 +1,91 @@ +# Cortex Linux Full Disk Encryption (FDE) UEFI Partitioning +# LUKS2 encrypted LVM for security-focused installations +# +# Partition layout: +# - 512MB EFI System Partition (ESP) - unencrypted +# - 1GB /boot (ext4) - unencrypted +# - LUKS2 encrypted container: +# - LVM Volume Group (cortex-vg): +# - 20GB / (ext4) +# - 8GB swap (encrypted) +# - Remaining /home (ext4) +# +# Note: Passphrase should be provided via boot parameter or +# configured in preseed. For automated installs, consider +# using a key file or TPM integration in first-boot. + +### Partitioning +d-i partman-auto/method string crypto +d-i partman-auto/disk string /dev/sda + +# Use GPT partitioning for UEFI +d-i partman-partitioning/choose_label string gpt +d-i partman-partitioning/default_label string gpt + +# Crypto configuration +d-i partman-crypto/confirm boolean true +d-i partman-crypto/weak_passphrase boolean true +d-i partman-crypto/confirm_nooverwrite boolean true + +# LUKS configuration +# Note: In production, this passphrase should be passed via kernel params +# or replaced during first-boot with a strong passphrase or TPM enrollment +d-i partman-crypto/passphrase string cortex-temp-passphrase +d-i partman-crypto/passphrase-again string cortex-temp-passphrase + +# LVM configuration +d-i partman-auto-lvm/guided_size string max +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true +d-i partman-auto-lvm/new_vg_name string cortex-vg + +# Define partition recipe +d-i partman-auto/expert_recipe string \ + cortex-fde :: \ + 512 512 512 fat32 \ + $primary{ } \ + $iflabel{ gpt } \ + $reusemethod{ } \ + method{ efi } \ + format{ } \ + . \ + 1024 1024 1024 ext4 \ + $primary{ } \ + $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /boot } \ + . \ + 20480 20480 20480 ext4 \ + $lvmok{ } \ + lv_name{ root } \ + in_vg{ cortex-vg } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . \ + 8192 8192 8192 linux-swap \ + $lvmok{ } \ + lv_name{ swap } \ + in_vg{ cortex-vg } \ + method{ swap } format{ } \ + . \ + 16384 32768 -1 ext4 \ + $lvmok{ } \ + lv_name{ home } \ + in_vg{ cortex-vg } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /home } \ + . + +# Confirm partitioning without asking +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true +d-i partman-efi/non_efi_system boolean true + +# Skip LUKS warning about weak passphrase (will be changed at first-boot) +d-i partman-crypto/weak_passphrase boolean true diff --git a/iso/preseed/partitioning/lvm-uefi.preseed b/iso/preseed/partitioning/lvm-uefi.preseed new file mode 100644 index 0000000..e650164 --- /dev/null +++ b/iso/preseed/partitioning/lvm-uefi.preseed @@ -0,0 +1,69 @@ +# Cortex Linux LVM UEFI Partitioning +# LVM-based partitioning for flexible volume management +# +# Partition layout: +# - 512MB EFI System Partition (ESP) +# - 1GB /boot (ext4, outside LVM) +# - LVM Volume Group (cortex-vg): +# - 20GB / (ext4) +# - 8GB swap +# - Remaining /home (ext4) + +### Partitioning +d-i partman-auto/method string lvm +d-i partman-auto/disk string /dev/sda + +# Use GPT partitioning for UEFI +d-i partman-partitioning/choose_label string gpt +d-i partman-partitioning/default_label string gpt + +# LVM configuration +d-i partman-auto-lvm/guided_size string max +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true +d-i partman-auto-lvm/new_vg_name string cortex-vg + +# Define partition recipe +d-i partman-auto/expert_recipe string \ + cortex-lvm :: \ + 512 512 512 fat32 \ + $primary{ } \ + $iflabel{ gpt } \ + $reusemethod{ } \ + method{ efi } \ + format{ } \ + . \ + 1024 1024 1024 ext4 \ + $primary{ } \ + $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /boot } \ + . \ + 20480 20480 20480 ext4 \ + $lvmok{ } \ + lv_name{ root } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . \ + 8192 8192 8192 linux-swap \ + $lvmok{ } \ + lv_name{ swap } \ + method{ swap } format{ } \ + . \ + 16384 32768 -1 ext4 \ + $lvmok{ } \ + lv_name{ home } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /home } \ + . + +# Confirm partitioning without asking +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true +d-i partman-efi/non_efi_system boolean true diff --git a/iso/preseed/partitioning/raid1-uefi.preseed b/iso/preseed/partitioning/raid1-uefi.preseed new file mode 100644 index 0000000..fb24715 --- /dev/null +++ b/iso/preseed/partitioning/raid1-uefi.preseed @@ -0,0 +1,78 @@ +# Cortex Linux RAID1 UEFI Partitioning +# Software RAID1 (mirroring) for high availability +# +# Requires two identical disks (/dev/sda and /dev/sdb) +# +# Partition layout (mirrored on both disks): +# - 512MB EFI System Partition (ESP) on each disk +# - 1GB /boot RAID1 (ext4) +# - RAID1 for remaining space: +# - LVM Volume Group (cortex-vg): +# - 20GB / (ext4) +# - 8GB swap +# - Remaining /home (ext4) + +### Partitioning +d-i partman-auto/method string raid +d-i partman-auto/disk string /dev/sda /dev/sdb + +# Use GPT partitioning for UEFI +d-i partman-partitioning/choose_label string gpt +d-i partman-partitioning/default_label string gpt + +# RAID and LVM configuration +d-i partman-md/device_remove_md boolean true +d-i partman-md/confirm boolean true +d-i partman-md/confirm_nooverwrite boolean true +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true +d-i partman-auto-lvm/new_vg_name string cortex-vg +d-i partman-auto-lvm/guided_size string max + +# Define partition recipe for RAID +d-i partman-auto/expert_recipe string \ + cortex-raid :: \ + 512 512 512 fat32 \ + $primary{ } \ + $iflabel{ gpt } \ + $reusemethod{ } \ + method{ efi } \ + format{ } \ + . \ + 1024 1024 1024 raid \ + $primary{ } \ + $bootable{ } \ + method{ raid } \ + . \ + 10000 50000 -1 raid \ + $primary{ } \ + method{ raid } \ + . + +# RAID configuration +d-i partman-auto-raid/recipe string \ + 1 2 0 ext4 /boot \ + /dev/sda2#/dev/sdb2 \ + . \ + 1 2 0 lvm - \ + /dev/sda3#/dev/sdb3 \ + . + +# LVM on top of RAID +d-i partman-auto-lvm/new_vg_name string cortex-vg + +# Logical volumes on the RAID1 LVM +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true + +# Confirm partitioning without asking +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true +d-i partman-md/confirm_nooverwrite boolean true +d-i partman-efi/non_efi_system boolean true + +# Additional packages for RAID management +d-i pkgsel/include string mdadm lvm2 diff --git a/iso/preseed/partitioning/simple-bios.preseed b/iso/preseed/partitioning/simple-bios.preseed new file mode 100644 index 0000000..0937aa7 --- /dev/null +++ b/iso/preseed/partitioning/simple-bios.preseed @@ -0,0 +1,43 @@ +# Cortex Linux Simple BIOS Partitioning +# Standard MBR partitioning for legacy BIOS systems +# +# Partition layout: +# - 1MB BIOS boot partition (for GRUB) +# - 1GB /boot (ext4) +# - Remaining space / (ext4) + +### Partitioning +d-i partman-auto/method string regular +d-i partman-auto/disk string /dev/sda + +# Use MBR for BIOS +d-i partman-partitioning/choose_label string msdos +d-i partman-partitioning/default_label string msdos + +# Define partition recipe +d-i partman-auto/expert_recipe string \ + cortex-bios :: \ + 1 1 1 free \ + $primary{ } \ + $bios_boot{ } \ + method{ biosgrub } \ + . \ + 1024 1024 1024 ext4 \ + $primary{ } \ + $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /boot } \ + . \ + 8192 16384 -1 ext4 \ + $primary{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . + +# Confirm partitioning without asking +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true diff --git a/iso/preseed/partitioning/simple-uefi.preseed b/iso/preseed/partitioning/simple-uefi.preseed new file mode 100644 index 0000000..9b4c072 --- /dev/null +++ b/iso/preseed/partitioning/simple-uefi.preseed @@ -0,0 +1,48 @@ +# Cortex Linux Simple UEFI Partitioning +# Standard GPT partitioning for UEFI systems without LVM or encryption +# +# Partition layout: +# - 512MB EFI System Partition (ESP) +# - 1GB /boot (ext4) +# - Remaining space / (ext4) + +### Partitioning +d-i partman-auto/method string regular +d-i partman-auto/disk string /dev/sda + +# Use GPT partitioning for UEFI +d-i partman-partitioning/choose_label string gpt +d-i partman-partitioning/default_label string gpt + +# Define partition recipe +d-i partman-auto/expert_recipe string \ + cortex-simple :: \ + 512 512 512 fat32 \ + $primary{ } \ + $iflabel{ gpt } \ + $reusemethod{ } \ + method{ efi } \ + format{ } \ + . \ + 1024 1024 1024 ext4 \ + $primary{ } \ + $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /boot } \ + . \ + 8192 16384 -1 ext4 \ + $primary{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . + +# Confirm partitioning without asking +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +# Force UEFI installation +d-i partman-efi/non_efi_system boolean true diff --git a/iso/provisioning/cortex-first-boot.service b/iso/provisioning/cortex-first-boot.service new file mode 100644 index 0000000..61ac3bf --- /dev/null +++ b/iso/provisioning/cortex-first-boot.service @@ -0,0 +1,27 @@ +[Unit] +Description=Cortex Linux First-Boot Provisioning +Documentation=https://github.com/cortexlinux/cortex-distro +After=network-pre.target systemd-resolved.service +Before=network.target getty@tty1.service display-manager.service +Wants=network-pre.target +ConditionPathExists=!/opt/cortex/provisioning/.first-boot-complete + +[Service] +Type=oneshot +ExecStart=/opt/cortex/provisioning/first-boot.sh +RemainAfterExit=yes +TimeoutSec=600 + +# Security hardening for the service itself +NoNewPrivileges=false +ProtectSystem=false +ProtectHome=false +PrivateTmp=true + +# Logging +StandardOutput=journal+console +StandardError=journal+console +SyslogIdentifier=cortex-first-boot + +[Install] +WantedBy=multi-user.target diff --git a/iso/provisioning/first-boot.sh b/iso/provisioning/first-boot.sh new file mode 100644 index 0000000..9f41075 --- /dev/null +++ b/iso/provisioning/first-boot.sh @@ -0,0 +1,406 @@ +#!/bin/bash +# +# Cortex Linux First-Boot Provisioning Script +# +# This script runs once at first boot to complete system setup. +# It is designed to be: +# - Idempotent: Safe to run multiple times +# - Offline-capable: Core functionality works without network +# +# Exit codes: +# 0 - Success +# 1 - General error +# 3 - Required command missing +# + +set -euo pipefail + +readonly CORTEX_DIR="/opt/cortex" +readonly PROVISION_DIR="${CORTEX_DIR}/provisioning" +readonly LOG_DIR="/var/log/cortex" +readonly LOG_FILE="${LOG_DIR}/first-boot.log" +readonly STATE_FILE="${PROVISION_DIR}/.first-boot-complete" + +# Logging functions +log() { + local level="$1" + shift + local message="$*" + local timestamp + timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo "[${timestamp}] [${level}] ${message}" | tee -a "${LOG_FILE}" +} + +log_info() { log "INFO" "$@"; } +log_warn() { log "WARN" "$@"; } +log_error() { log "ERROR" "$@"; } + +# Check if already completed +check_already_complete() { + if [[ -f "${STATE_FILE}" ]]; then + log_info "First-boot provisioning already completed. Exiting." + exit 0 + fi +} + +# Initialize logging +init_logging() { + mkdir -p "${LOG_DIR}" + touch "${LOG_FILE}" + chmod 640 "${LOG_FILE}" + log_info "=== Cortex Linux First-Boot Provisioning Started ===" + log_info "Hostname: $(hostname)" + log_info "Date: $(date)" + log_info "Kernel: $(uname -r)" +} + + +# Check network connectivity (non-blocking) +check_network() { + if ping -c 1 -W 3 8.8.8.8 &>/dev/null; then + log_info "Network: Online" + export NETWORK_AVAILABLE=true + else + log_warn "Network: Offline (some features may be skipped)" + export NETWORK_AVAILABLE=false + fi +} + +# Generate machine-id if not present +setup_machine_id() { + log_info "Setting up machine-id..." + + if [[ ! -s /etc/machine-id ]]; then + systemd-machine-id-setup + log_info "Generated new machine-id" + else + log_info "Machine-id already exists" + fi +} + +# Configure sudo for cortex user +setup_sudo() { + log_info "Configuring sudo..." + + local sudoers_file="/etc/sudoers.d/cortex" + + if [[ ! -f "${sudoers_file}" ]]; then + cat > "${sudoers_file}" << 'EOF' +# Cortex Linux sudo configuration +# Allow cortex user to run sudo with password +cortex ALL=(ALL:ALL) ALL + +# Secure defaults +Defaults env_reset +Defaults mail_badpass +Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +Defaults use_pty +Defaults logfile="/var/log/sudo.log" +EOF + chmod 440 "${sudoers_file}" + log_info "Sudo configured for cortex user" + else + log_info "Sudo already configured" + fi +} + +# Force password change on first login +setup_password_change() { + if [[ "${REQUIRE_PASSWORD_CHANGE:-false}" == "true" ]]; then + log_info "Forcing password change on first login..." + chage -d 0 cortex + log_info "Password change required for cortex user" + fi +} + +# Configure SSH hardening +setup_ssh() { + log_info "Configuring SSH..." + + local sshd_config="/etc/ssh/sshd_config.d/cortex-hardening.conf" + + if [[ ! -f "${sshd_config}" ]]; then + mkdir -p /etc/ssh/sshd_config.d + cat > "${sshd_config}" << 'EOF' +# Cortex Linux SSH Hardening +# Disable root login +PermitRootLogin no + +# Disable password authentication for root +PasswordAuthentication yes +PubkeyAuthentication yes + +# Disable empty passwords +PermitEmptyPasswords no + +# Limit authentication attempts +MaxAuthTries 3 + +# Disable X11 forwarding (enable if needed) +X11Forwarding no + +# Client alive settings +ClientAliveInterval 300 +ClientAliveCountMax 2 + +# Disable TCP forwarding by default +AllowTcpForwarding no + +# Use strong ciphers only +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com + +# Use strong MACs +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com + +# Use strong key exchange +KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org +EOF + chmod 644 "${sshd_config}" + log_info "SSH hardening configured" + + # Reload SSH if running + if systemctl is-active --quiet sshd; then + systemctl reload sshd || true + fi + else + log_info "SSH hardening already configured" + fi +} + +# Configure firewall (UFW) +setup_firewall() { + log_info "Configuring firewall..." + + if command -v ufw &>/dev/null; then + # Check if UFW is already configured + if ! ufw status | grep -q "Status: active"; then + # Default policies + ufw default deny incoming + ufw default allow outgoing + + # Allow SSH + ufw allow ssh + + # Enable UFW + echo "y" | ufw enable + log_info "UFW firewall enabled" + else + log_info "UFW already active" + fi + else + log_warn "UFW not installed, skipping firewall configuration" + fi +} + +# Configure fail2ban +setup_fail2ban() { + log_info "Configuring fail2ban..." + + if command -v fail2ban-client &>/dev/null; then + local jail_local="/etc/fail2ban/jail.local" + + if [[ ! -f "${jail_local}" ]]; then + cat > "${jail_local}" << 'EOF' +# Cortex Linux fail2ban configuration +[DEFAULT] +bantime = 1h +findtime = 10m +maxretry = 5 + +# Email notifications (configure if needed) +# destemail = admin@example.com +# sendername = Fail2Ban +# mta = sendmail + +[sshd] +enabled = true +port = ssh +filter = sshd +logpath = /var/log/auth.log +maxretry = 3 +bantime = 1h +EOF + chmod 644 "${jail_local}" + systemctl enable fail2ban + systemctl restart fail2ban + log_info "fail2ban configured and enabled" + else + log_info "fail2ban already configured" + fi + else + log_warn "fail2ban not installed, skipping" + fi +} + +# Configure automatic security updates +setup_unattended_upgrades() { + log_info "Configuring automatic security updates..." + + if command -v unattended-upgrade &>/dev/null; then + local auto_upgrades="/etc/apt/apt.conf.d/20auto-upgrades" + + if [[ ! -f "${auto_upgrades}" ]]; then + cat > "${auto_upgrades}" << 'EOF' +APT::Periodic::Update-Package-Lists "1"; +APT::Periodic::Unattended-Upgrade "1"; +APT::Periodic::Download-Upgradeable-Packages "1"; +APT::Periodic::AutocleanInterval "7"; +EOF + log_info "Automatic security updates enabled" + else + log_info "Automatic updates already configured" + fi + else + log_warn "unattended-upgrades not installed, skipping" + fi +} + +# Desktop environment setup +setup_desktop() { + log_info "Configuring desktop environment..." + + # Add Flathub repository if flatpak is installed + if command -v flatpak &>/dev/null && [[ "${NETWORK_AVAILABLE}" == "true" ]]; then + if ! flatpak remote-list | grep -q flathub; then + flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo || true + log_info "Flathub repository added" + fi + fi + + # Configure Docker for cortex user + if command -v docker &>/dev/null; then + if ! groups cortex | grep -q docker; then + usermod -aG docker cortex + log_info "Added cortex user to docker group" + fi + fi +} + +# Add Cortex repository (requires network) +setup_cortex_repository() { + if [[ "${NETWORK_AVAILABLE}" != "true" ]]; then + log_warn "Network unavailable, skipping Cortex repository setup" + return 0 + fi + + log_info "Setting up Cortex package repository..." + + local keyring_dir="/usr/share/keyrings" + local sources_file="/etc/apt/sources.list.d/cortex-linux.list" + + # Check if already configured (from live image or previous run) + if [[ -f "${sources_file}" ]]; then + log_info "Cortex repository already configured" + return 0 + fi + + log_info "Adding Cortex Linux APT repository..." + + # Download and install GPG key + if curl -fsSL https://apt.cortexlinux.com/keys/cortex-linux.gpg.asc | gpg --dearmor -o "${keyring_dir}/cortex-linux.gpg"; then + log_info "Cortex GPG key installed" + else + log_error "Failed to download Cortex GPG key" + return 1 + fi + + # Add repository source + echo "deb [signed-by=${keyring_dir}/cortex-linux.gpg] https://apt.cortexlinux.com stable main" > "${sources_file}" + + # Update package lists + if apt-get update -qq; then + log_info "Cortex repository configured successfully" + else + log_warn "apt-get update failed, repository may not be accessible" + fi +} + +# Generate SSH host keys if missing +setup_ssh_keys() { + log_info "Checking SSH host keys..." + + local keys_generated=false + + for keytype in rsa ecdsa ed25519; do + local keyfile="/etc/ssh/ssh_host_${keytype}_key" + if [[ ! -f "${keyfile}" ]]; then + ssh-keygen -t "${keytype}" -f "${keyfile}" -N "" -q + keys_generated=true + log_info "Generated SSH ${keytype} host key" + fi + done + + if [[ "${keys_generated}" == "true" ]]; then + systemctl restart sshd || true + fi +} + +# Cleanup temporary installation artifacts +cleanup() { + log_info "Cleaning up installation artifacts..." + + # Remove installer logs that may contain sensitive info + if [ -d /var/log/installer ]; then + rm -f /var/log/installer/* + fi + + # Clear apt cache + apt-get clean + + log_info "Cleanup complete" +} + +# Mark provisioning as complete +mark_complete() { + local completion_time + completion_time=$(date '+%Y-%m-%d %H:%M:%S') + + cat > "${STATE_FILE}" << EOF +# Cortex Linux First-Boot Provisioning +# Completed: ${completion_time} +# Hostname: $(hostname) +COMPLETED=true +TIMESTAMP=${completion_time} +EOF + + chmod 644 "${STATE_FILE}" + log_info "=== First-Boot Provisioning Complete ===" +} + +# Main execution +main() { + check_already_complete + init_logging + check_network + + # Core setup + setup_machine_id + setup_sudo + setup_ssh_keys + setup_ssh + setup_password_change + + # Security setup + setup_firewall + setup_fail2ban + setup_unattended_upgrades + + # Desktop setup (if applicable) + setup_desktop + + # Repository setup (requires network) + setup_cortex_repository + + cleanup + mark_complete + + # Disable the first-boot service after completion + if systemctl is-enabled cortex-first-boot.service &>/dev/null; then + systemctl disable cortex-first-boot.service + fi + + log_info "System will continue to boot normally." +} + +# Run main function +main "$@" diff --git a/packages/cortex-branding/.gitignore b/packages/cortex-branding/.gitignore new file mode 100644 index 0000000..37b63d2 --- /dev/null +++ b/packages/cortex-branding/.gitignore @@ -0,0 +1,13 @@ +# dpkg-buildpackage artifacts +debian/cortex-branding/ +debian/files +debian/*.substvars +debian/.debhelper/ +debian/*.debhelper.log +debian/debhelper-build-stamp + +# Build outputs (stored in output/ instead) +*.deb +*.changes +*.buildinfo + diff --git a/packages/cortex-branding/Makefile b/packages/cortex-branding/Makefile new file mode 100644 index 0000000..4c13eca --- /dev/null +++ b/packages/cortex-branding/Makefile @@ -0,0 +1,221 @@ +# Cortex Linux Branding Asset Generator +# +# Generates branding assets from source images. +# This Makefile is part of the cortex-branding package. +# +# Run: make (builds only changed assets) +# Run: make clean (removes generated assets) +# Run: make all (force rebuild everything) +# + +# Source logo (in this directory) +LOGO_PRIMARY := source/cx-logo-primary.png + +# Colors +DARK_BG := \#0F0F23 +DARKER_BG := \#0A0A18 +PRIMARY_PURPLE := \#6B21A8 +ELECTRIC_CYAN := \#06B6D4 +SURFACE := \#1E1E3F +TEXT_LIGHT := \#E2E8F0 + +# Output directories (relative to this Makefile) +PLYMOUTH_DIR := usr/share/plymouth/themes/cortex +GRUB_DIR := boot/grub/themes/cortex +WALLPAPER_DIR := usr/share/backgrounds/cortex +LOGO_DIR := usr/share/cortex/logos + +# All targets +PLYMOUTH_ASSETS := $(PLYMOUTH_DIR)/logo.png $(PLYMOUTH_DIR)/entry.png $(PLYMOUTH_DIR)/bullet.png \ + $(PLYMOUTH_DIR)/dot-on.png $(PLYMOUTH_DIR)/dot-off.png + +GRUB_ASSETS := $(GRUB_DIR)/background.png $(GRUB_DIR)/icons/cortex.png $(GRUB_DIR)/icons/linux.png \ + $(GRUB_DIR)/icons/recovery.png $(GRUB_DIR)/select_c.png $(GRUB_DIR)/select_w.png \ + $(GRUB_DIR)/select_e.png $(GRUB_DIR)/scrollbar_thumb.png $(GRUB_DIR)/scrollbar_frame.png + +WALLPAPER_ASSETS := $(WALLPAPER_DIR)/minimal-dark.png $(WALLPAPER_DIR)/circuit-board.png + +LOGO_ASSETS := $(LOGO_DIR)/cortex-icon-128.png $(LOGO_DIR)/favicon-32.png + +ALL_ASSETS := $(PLYMOUTH_ASSETS) $(GRUB_ASSETS) $(WALLPAPER_ASSETS) $(LOGO_ASSETS) + +# Default target +.PHONY: default +default: $(ALL_ASSETS) + @echo "" + @echo "✓ Branding assets generated" + @echo "" + +# Force rebuild all +.PHONY: all +all: clean default + +# Clean generated assets +.PHONY: clean +clean: + @echo "Cleaning generated assets..." + rm -f $(PLYMOUTH_DIR)/*.png + rm -f $(GRUB_DIR)/*.png $(GRUB_DIR)/icons/*.png + rm -f $(WALLPAPER_DIR)/*.png + rm -f $(LOGO_DIR)/*.png + @echo "✓ Clean complete" + +# Create directories +$(PLYMOUTH_DIR) $(GRUB_DIR)/icons $(WALLPAPER_DIR) $(LOGO_DIR): + mkdir -p $@ + +# Helper function for logo extraction +define extract_logo + magick $(LOGO_PRIMARY) \ + -gravity center -crop 800x800+0+0 +repage \ + -resize $(1)x$(1) \ + -background none \ + -define png:color-type=6 \ + $(2) +endef + +# ============================================================================= +# Plymouth Assets +# ============================================================================= + +$(PLYMOUTH_DIR)/logo.png: $(LOGO_PRIMARY) | $(PLYMOUTH_DIR) + @echo " Plymouth: logo.png" + @$(call extract_logo,300,$@) + +$(PLYMOUTH_DIR)/entry.png: | $(PLYMOUTH_DIR) + @echo " Plymouth: entry.png" + @magick -size 300x40 xc:transparent \ + -fill "$(DARK_BG)" \ + -stroke "$(PRIMARY_PURPLE)" -strokewidth 2 \ + -draw "roundrectangle 2,2 297,37 8,8" \ + $@ + +$(PLYMOUTH_DIR)/bullet.png: | $(PLYMOUTH_DIR) + @echo " Plymouth: bullet.png" + @magick -size 15x15 xc:transparent \ + -fill "$(ELECTRIC_CYAN)" \ + -draw "circle 7,7 7,2" \ + $@ + +$(PLYMOUTH_DIR)/dot-on.png: | $(PLYMOUTH_DIR) + @echo " Plymouth: dot-on.png" + @magick -size 12x12 xc:transparent -fill white \ + -draw "circle 6,6 6,1" \ + -define png:color-type=6 \ + $@ + +$(PLYMOUTH_DIR)/dot-off.png: | $(PLYMOUTH_DIR) + @echo " Plymouth: dot-off.png" + @magick -size 12x12 xc:transparent -fill "rgb(80,80,80)" \ + -draw "circle 6,6 6,1" \ + -define png:color-type=6 \ + $@ + +# ============================================================================= +# GRUB Assets +# ============================================================================= + +$(GRUB_DIR)/background.png: | $(GRUB_DIR) + @echo " GRUB: background.png" + @magick -size 1920x1080 \ + "gradient:$(DARK_BG)-$(DARKER_BG)" \ + -rotate 180 \ + \( -size 1920x1080 xc:transparent \ + -fill "rgba(107,33,168,0.03)" \ + -draw "line 0,200 1920,200" \ + -draw "line 0,400 1920,400" \ + -draw "line 0,600 1920,600" \ + -draw "line 0,800 1920,800" \ + -draw "line 400,0 400,1080" \ + -draw "line 800,0 800,1080" \ + -draw "line 1200,0 1200,1080" \ + -draw "line 1600,0 1600,1080" \ + \) -composite \ + $@ + +$(GRUB_DIR)/icons/cortex.png: $(LOGO_PRIMARY) | $(GRUB_DIR)/icons + @echo " GRUB: icons/cortex.png" + @$(call extract_logo,32,$@) + +$(GRUB_DIR)/icons/linux.png: | $(GRUB_DIR)/icons + @echo " GRUB: icons/linux.png" + @magick -size 32x32 xc:transparent \ + -fill "$(TEXT_LIGHT)" -draw "polygon 16,4 6,28 26,28" \ + -fill "$(DARK_BG)" -draw "polygon 16,10 10,24 22,24" \ + $@ + +$(GRUB_DIR)/icons/recovery.png: | $(GRUB_DIR)/icons + @echo " GRUB: icons/recovery.png" + @magick -size 32x32 xc:transparent \ + -fill "$(ELECTRIC_CYAN)" -stroke "$(ELECTRIC_CYAN)" -strokewidth 2 \ + -draw "arc 6,6 26,26 0,270" -draw "polygon 24,6 28,12 20,12" \ + $@ + +$(GRUB_DIR)/select_c.png: | $(GRUB_DIR) + @magick -size 10x40 xc:transparent -fill "rgba(107,33,168,0.6)" -draw "rectangle 0,0 9,39" $@ + +$(GRUB_DIR)/select_w.png: | $(GRUB_DIR) + @magick -size 10x40 xc:transparent -fill "rgba(107,33,168,0.6)" -draw "roundrectangle 0,0 19,39 8,8" -crop 10x40+0+0 +repage $@ + +$(GRUB_DIR)/select_e.png: | $(GRUB_DIR) + @magick -size 10x40 xc:transparent -fill "rgba(107,33,168,0.6)" -draw "roundrectangle -10,0 9,39 8,8" $@ + +$(GRUB_DIR)/scrollbar_thumb.png: | $(GRUB_DIR) + @magick -size 10x30 xc:transparent -fill "$(PRIMARY_PURPLE)" -draw "roundrectangle 2,2 7,27 3,3" $@ + +$(GRUB_DIR)/scrollbar_frame.png: | $(GRUB_DIR) + @magick -size 10x100 xc:transparent -fill "$(SURFACE)" -draw "roundrectangle 3,3 6,96 2,2" $@ + +# ============================================================================= +# Wallpapers +# ============================================================================= + +$(WALLPAPER_DIR)/minimal-dark.png: $(LOGO_PRIMARY) | $(WALLPAPER_DIR) + @echo " Wallpaper: minimal-dark.png" + @magick -size 1920x1080 \ + "gradient:$(DARK_BG)-$(DARKER_BG)" \ + -rotate 180 \ + \( $(LOGO_PRIMARY) -gravity center -crop 800x800+0+0 +repage -resize 280x280 \) \ + -gravity center -composite \ + $@ + +$(WALLPAPER_DIR)/circuit-board.png: $(LOGO_PRIMARY) | $(WALLPAPER_DIR) + @echo " Wallpaper: circuit-board.png" + @magick -size 1920x1080 \ + "gradient:$(DARK_BG)-$(DARKER_BG)" \ + -rotate 180 \ + -stroke "rgba(107,33,168,0.10)" -strokewidth 2 \ + -draw "line 100,0 100,300" -draw "line 100,300 300,300" \ + -draw "line 300,300 300,500" -draw "line 300,500 500,500" \ + -draw "line 700,0 700,200" -draw "line 700,200 900,200" \ + -draw "line 900,200 900,400" -draw "line 900,400 1100,400" \ + -draw "line 1400,0 1400,300" -draw "line 1400,300 1600,300" \ + -draw "line 1600,300 1600,500" -draw "line 1600,500 1800,500" \ + -draw "line 200,1080 200,800" -draw "line 200,800 400,800" \ + -draw "line 800,1080 800,900" -draw "line 800,900 1000,900" \ + -draw "line 1500,1080 1500,800" -draw "line 1500,800 1700,800" \ + -fill "rgba(6,182,212,0.25)" \ + -draw "circle 100,300 100,306" -draw "circle 300,500 300,306" \ + -draw "circle 500,500 500,306" -draw "circle 700,200 700,206" \ + -draw "circle 900,400 900,206" -draw "circle 1100,400 1100,206" \ + -draw "circle 1400,300 1400,206" -draw "circle 1600,500 1600,206" \ + -fill "rgba(107,33,168,0.20)" \ + -draw "circle 200,800 200,207" -draw "circle 400,800 400,206" \ + -draw "circle 800,900 800,207" -draw "circle 1000,900 1000,206" \ + -draw "circle 1500,800 1500,207" -draw "circle 1700,800 1700,206" \ + \( $(LOGO_PRIMARY) -gravity center -crop 800x800+0+0 +repage -resize 280x280 \) \ + -gravity center -composite \ + $@ + +# ============================================================================= +# Logos +# ============================================================================= + +$(LOGO_DIR)/cortex-icon-128.png: $(LOGO_PRIMARY) | $(LOGO_DIR) + @echo " Logo: cortex-icon-128.png" + @$(call extract_logo,128,$@) + +$(LOGO_DIR)/favicon-32.png: $(LOGO_PRIMARY) | $(LOGO_DIR) + @echo " Logo: favicon-32.png" + @$(call extract_logo,32,$@) + diff --git a/packages/cortex-branding/boot/grub/themes/cortex/background.png b/packages/cortex-branding/boot/grub/themes/cortex/background.png new file mode 100644 index 0000000..850f919 Binary files /dev/null and b/packages/cortex-branding/boot/grub/themes/cortex/background.png differ diff --git a/packages/cortex-branding/boot/grub/themes/cortex/icons/cortex.png b/packages/cortex-branding/boot/grub/themes/cortex/icons/cortex.png new file mode 100644 index 0000000..0e055d0 Binary files /dev/null and b/packages/cortex-branding/boot/grub/themes/cortex/icons/cortex.png differ diff --git a/packages/cortex-branding/boot/grub/themes/cortex/icons/linux.png b/packages/cortex-branding/boot/grub/themes/cortex/icons/linux.png new file mode 100644 index 0000000..3aadfa0 Binary files /dev/null and b/packages/cortex-branding/boot/grub/themes/cortex/icons/linux.png differ diff --git a/packages/cortex-branding/boot/grub/themes/cortex/icons/recovery.png b/packages/cortex-branding/boot/grub/themes/cortex/icons/recovery.png new file mode 100644 index 0000000..5d1f6b9 Binary files /dev/null and b/packages/cortex-branding/boot/grub/themes/cortex/icons/recovery.png differ diff --git a/packages/cortex-branding/boot/grub/themes/cortex/scrollbar_frame.png b/packages/cortex-branding/boot/grub/themes/cortex/scrollbar_frame.png new file mode 100644 index 0000000..c1ed9fd Binary files /dev/null and b/packages/cortex-branding/boot/grub/themes/cortex/scrollbar_frame.png differ diff --git a/packages/cortex-branding/boot/grub/themes/cortex/scrollbar_thumb.png b/packages/cortex-branding/boot/grub/themes/cortex/scrollbar_thumb.png new file mode 100644 index 0000000..45401cc Binary files /dev/null and b/packages/cortex-branding/boot/grub/themes/cortex/scrollbar_thumb.png differ diff --git a/packages/cortex-branding/boot/grub/themes/cortex/select_c.png b/packages/cortex-branding/boot/grub/themes/cortex/select_c.png new file mode 100644 index 0000000..fcc7d3f Binary files /dev/null and b/packages/cortex-branding/boot/grub/themes/cortex/select_c.png differ diff --git a/packages/cortex-branding/boot/grub/themes/cortex/select_e.png b/packages/cortex-branding/boot/grub/themes/cortex/select_e.png new file mode 100644 index 0000000..878968b Binary files /dev/null and b/packages/cortex-branding/boot/grub/themes/cortex/select_e.png differ diff --git a/packages/cortex-branding/boot/grub/themes/cortex/select_w.png b/packages/cortex-branding/boot/grub/themes/cortex/select_w.png new file mode 100644 index 0000000..8ab0988 Binary files /dev/null and b/packages/cortex-branding/boot/grub/themes/cortex/select_w.png differ diff --git a/packages/cortex-branding/boot/grub/themes/cortex/theme.txt b/packages/cortex-branding/boot/grub/themes/cortex/theme.txt new file mode 100644 index 0000000..9b26fed --- /dev/null +++ b/packages/cortex-branding/boot/grub/themes/cortex/theme.txt @@ -0,0 +1,89 @@ +# Cortex Linux GRUB Theme +# Modern boot menu with neural network aesthetics + +# Global properties +title-text: "" +desktop-image: "background.png" +desktop-color: "#0F0F23" +message-color: "#94A3B8" +message-bg-color: "#0F0F23" +terminal-font: "DejaVu Sans Mono Regular 14" +terminal-box: "terminal_box_*.png" + +# Boot menu ++ boot_menu { + left = 15% + top = 25% + width = 70% + height = 50% + item_font = "DejaVu Sans Regular 14" + item_color = "#E2E8F0" + selected_item_font = "DejaVu Sans Bold 14" + selected_item_color = "#06B6D4" + item_height = 36 + item_padding = 12 + item_spacing = 4 + selected_item_color = "#06B6D4" +} + +# Title label (Cortex Linux) ++ label { + left = 50%-100 + top = 8% + width = 200 + height = 40 + text = "CORTEX LINUX" + font = "DejaVu Sans Bold 24" + color = "#ffffff" + align = "center" +} + +# Subtitle ++ label { + left = 50%-120 + top = 14% + width = 240 + height = 25 + text = "AI-Powered Linux Distribution" + font = "DejaVu Sans Regular 12" + color = "#6B21A8" + align = "center" +} + +# Countdown timer ++ label { + left = 50%-150 + top = 80% + width = 300 + height = 25 + id = "__timeout__" + text = "Booting in %d seconds..." + font = "DejaVu Sans Regular 12" + color = "#64748B" + align = "center" +} + +# Help text ++ label { + left = 50%-180 + top = 90% + width = 360 + height = 20 + text = "Press 'e' to edit options | 'c' for command line" + font = "DejaVu Sans Regular 10" + color = "#475569" + align = "center" +} + +# Progress bar (for countdown) ++ progress_bar { + id = "__timeout__" + left = 30% + top = 85% + width = 40% + height = 8 + bg_color = "#1E1E3F" + fg_color = "#6B21A8" + border_color = "#2D2D5A" + text_color = "#00000000" +} diff --git a/packages/cortex-branding/debian/changelog b/packages/cortex-branding/debian/changelog new file mode 100644 index 0000000..3f3a0eb --- /dev/null +++ b/packages/cortex-branding/debian/changelog @@ -0,0 +1,14 @@ +cortex-branding (1.0.0) stable; urgency=medium + + * Initial release + * OS identity files (os-release, lsb-release, issue) + * Plymouth boot splash theme + * GRUB bootloader theme with Cortex branding + * Desktop wallpapers collection + * GDM login screen dconf configuration + * Terminal MOTD scripts + * Neofetch configuration and custom ASCII art + * System logos and icons + + -- Cortex Linux Team Sat, 17 Jan 2026 00:00:00 +0000 + diff --git a/packages/cortex-branding/debian/control b/packages/cortex-branding/debian/control new file mode 100644 index 0000000..bec0933 --- /dev/null +++ b/packages/cortex-branding/debian/control @@ -0,0 +1,38 @@ +Source: cortex-branding +Section: misc +Priority: optional +Maintainer: Cortex Linux Team +Build-Depends: debhelper-compat (= 13) +Standards-Version: 4.6.2 +Homepage: https://cortexlinux.com +Vcs-Browser: https://github.com/cortexlinux/cortex-distro +Vcs-Git: https://github.com/cortexlinux/cortex-distro.git +Rules-Requires-Root: no + +Package: cortex-branding +Architecture: all +Depends: ${misc:Depends}, + plymouth, + plymouth-themes +Recommends: + gnome-shell, + gdm3 +Suggests: + neofetch +Description: Cortex Linux branding and visual identity + This package provides the complete Cortex Linux branding including: + - OS identity files (/etc/os-release, /etc/lsb-release) + - Plymouth boot splash theme + - GRUB bootloader theme + - Desktop wallpapers + - GDM login screen styling + - Terminal MOTD (Message of the Day) + - Neofetch configuration and ASCII art + - System logos and icons + . + Installing this package will replace Debian/Ubuntu branding with + Cortex Linux branding throughout the system. + . + The package works on any Debian-based distribution (Debian, Ubuntu, + Linux Mint, etc.) and can be installed via apt or dpkg. + diff --git a/packages/cortex-branding/debian/copyright b/packages/cortex-branding/debian/copyright new file mode 100644 index 0000000..796eb9e --- /dev/null +++ b/packages/cortex-branding/debian/copyright @@ -0,0 +1,28 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: cortex-branding +Upstream-Contact: Cortex Linux Team +Source: https://github.com/cortexlinux/cortex-distro + +Files: * +Copyright: 2024-2026 Cortex Linux Team +License: MIT + +License: MIT + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + diff --git a/packages/cortex-branding/debian/postinst b/packages/cortex-branding/debian/postinst new file mode 100644 index 0000000..13fefa4 --- /dev/null +++ b/packages/cortex-branding/debian/postinst @@ -0,0 +1,165 @@ +#!/bin/bash +# +# Cortex Branding Post-Installation Script +# +# This script configures the system after cortex-branding package is installed. +# It sets up Plymouth, GRUB, MOTD, GDM, and other branding elements. +# +# Compatible with: +# - Live-build (ISO creation) +# - apt install (end-user installation) +# - dpkg -i (manual installation) +# + +set -e + +case "$1" in + configure) + echo "Configuring Cortex Linux branding..." + + # ==================================================================== + # OS Identity Files (copy templates to avoid base-files conflict) + # ==================================================================== + + if [ -d /usr/share/cortex/templates ]; then + echo " -> Installing OS identity files..." + cp -f /usr/share/cortex/templates/os-release /etc/os-release + cp -f /usr/share/cortex/templates/lsb-release /etc/lsb-release + cp -f /usr/share/cortex/templates/issue /etc/issue + cp -f /usr/share/cortex/templates/issue.net /etc/issue.net + fi + + # ==================================================================== + # Plymouth Theme Configuration + # ==================================================================== + + if [ -f /usr/share/plymouth/themes/cortex/cortex.plymouth ]; then + # Register with update-alternatives at high priority + if command -v update-alternatives &>/dev/null; then + update-alternatives --install /usr/share/plymouth/themes/default.plymouth default.plymouth \ + /usr/share/plymouth/themes/cortex/cortex.plymouth 200 || true + update-alternatives --set default.plymouth \ + /usr/share/plymouth/themes/cortex/cortex.plymouth || true + fi + + # Set theme via plymouth command + if command -v plymouth-set-default-theme &>/dev/null; then + plymouth-set-default-theme cortex || true + fi + + # Set in plymouthd.defaults as fallback + if [ -f /usr/share/plymouth/plymouthd.defaults ]; then + sed -i 's|^Theme=.*|Theme=cortex|' /usr/share/plymouth/plymouthd.defaults + else + mkdir -p /usr/share/plymouth + cat > /usr/share/plymouth/plymouthd.defaults << 'EOF' +[Daemon] +Theme=cortex +EOF + fi + + # Update initramfs to include Plymouth theme + if command -v update-initramfs &>/dev/null; then + update-initramfs -u || true + fi + fi + + # ==================================================================== + # GRUB Theme Configuration + # ==================================================================== + + if [ -f /etc/default/grub ]; then + # Set GRUB theme path + if grep -q "^GRUB_THEME=" /etc/default/grub; then + sed -i 's|^GRUB_THEME=.*|GRUB_THEME="/boot/grub/themes/cortex/theme.txt"|' /etc/default/grub + else + echo 'GRUB_THEME="/boot/grub/themes/cortex/theme.txt"' >> /etc/default/grub + fi + + # Set distributor name + if grep -q "^GRUB_DISTRIBUTOR=" /etc/default/grub; then + sed -i 's|^GRUB_DISTRIBUTOR=.*|GRUB_DISTRIBUTOR="Cortex Linux"|' /etc/default/grub + else + echo 'GRUB_DISTRIBUTOR="Cortex Linux"' >> /etc/default/grub + fi + + # Update GRUB configuration + if command -v update-grub &>/dev/null; then + update-grub || true + fi + fi + + # ==================================================================== + # MOTD Configuration + # ==================================================================== + + if [ -d /etc/update-motd.d ]; then + # Make Cortex MOTD scripts executable + for script in 00-cortex-banner 10-cortex-sysinfo 20-cortex-updates 99-cortex-footer; do + [ -f "/etc/update-motd.d/$script" ] && chmod +x "/etc/update-motd.d/$script" + done + + # Disable default Ubuntu/Debian MOTD scripts + for f in /etc/update-motd.d/??-*; do + if [ -f "$f" ]; then + case "$(basename "$f")" in + *cortex*) ;; # Keep our scripts + *) chmod -x "$f" 2>/dev/null || true ;; + esac + fi + done + fi + + # ==================================================================== + # GDM/dconf Configuration + # ==================================================================== + + if command -v dconf &>/dev/null; then + dconf update || true + fi + + # ==================================================================== + # GDM Theme (GNOME Shell login screen) + # ==================================================================== + + if [ -f /usr/share/gnome-shell/theme/Cortex/gnome-shell.css ]; then + # Register Cortex GDM theme with update-alternatives + if command -v update-alternatives &>/dev/null; then + # Check if gdm3-theme alternative exists + if update-alternatives --list gdm3-theme.css &>/dev/null 2>&1; then + update-alternatives --install /usr/share/gnome-shell/theme/gdm3.css gdm3-theme.css \ + /usr/share/gnome-shell/theme/Cortex/gnome-shell.css 200 || true + update-alternatives --set gdm3-theme.css \ + /usr/share/gnome-shell/theme/Cortex/gnome-shell.css 2>/dev/null || true + fi + fi + echo " -> GDM theme installed (Cortex)" + fi + + # ==================================================================== + # GSettings Schema Compilation + # ==================================================================== + + if command -v glib-compile-schemas &>/dev/null; then + glib-compile-schemas /usr/share/glib-2.0/schemas/ || true + fi + + # ==================================================================== + # Done + # ==================================================================== + + echo "Cortex Linux branding installed successfully." + echo "Some changes may require a reboot to take effect." + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument '$1'" >&2 + exit 1 + ;; +esac + +exit 0 + diff --git a/packages/cortex-branding/debian/postrm b/packages/cortex-branding/debian/postrm new file mode 100644 index 0000000..96b2bc5 --- /dev/null +++ b/packages/cortex-branding/debian/postrm @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Cortex Branding Post-Removal Script +# +# Cleans up after the package is removed. +# + +set -e + +case "$1" in + purge|remove) + # Update initramfs to remove Plymouth theme + if command -v update-initramfs &>/dev/null; then + update-initramfs -u 2>/dev/null || true + fi + + # Update GRUB to remove theme reference + if [ -f /etc/default/grub ]; then + # Remove GRUB theme line if it points to cortex + if grep -q 'GRUB_THEME=.*/cortex/' /etc/default/grub; then + sed -i '/^GRUB_THEME=.*cortex/d' /etc/default/grub + fi + + # Restore default distributor + if grep -q 'GRUB_DISTRIBUTOR="Cortex Linux"' /etc/default/grub; then + sed -i 's|GRUB_DISTRIBUTOR="Cortex Linux"|GRUB_DISTRIBUTOR="Debian"|' /etc/default/grub + fi + + if command -v update-grub &>/dev/null; then + update-grub 2>/dev/null || true + fi + fi + + # Update dconf + if command -v dconf &>/dev/null; then + dconf update 2>/dev/null || true + fi + ;; + + upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + ;; + + *) + echo "postrm called with unknown argument '$1'" >&2 + exit 1 + ;; +esac + +exit 0 + diff --git a/packages/cortex-branding/debian/prerm b/packages/cortex-branding/debian/prerm new file mode 100644 index 0000000..e03bd60 --- /dev/null +++ b/packages/cortex-branding/debian/prerm @@ -0,0 +1,67 @@ +#!/bin/bash +# +# Cortex Branding Pre-Removal Script +# +# Restores default system branding when the package is removed. +# + +set -e + +case "$1" in + remove|upgrade|deconfigure) + echo "Removing Cortex Linux branding..." + + # Restore Debian OS identity files + # On Debian, /etc/os-release is a symlink to /usr/lib/os-release (from base-files) + if [ -f /usr/lib/os-release ]; then + echo " -> Restoring Debian OS identity files..." + ln -sf /usr/lib/os-release /etc/os-release + # Restore generic Debian issue files + echo "Debian GNU/Linux \\n \\l" > /etc/issue + echo "Debian GNU/Linux" > /etc/issue.net + # lsb-release can be regenerated by lsb-release package if installed + if command -v lsb_release &>/dev/null; then + cat > /etc/lsb-release << 'EOLSB' +DISTRIB_ID=Debian +DISTRIB_DESCRIPTION="Debian GNU/Linux" +EOLSB + fi + fi + + # Restore default Plymouth theme + if command -v update-alternatives &>/dev/null; then + update-alternatives --remove default.plymouth \ + /usr/share/plymouth/themes/cortex/cortex.plymouth 2>/dev/null || true + fi + + if command -v plymouth-set-default-theme &>/dev/null; then + plymouth-set-default-theme -R 2>/dev/null || true + fi + + # Remove GDM theme alternative + if command -v update-alternatives &>/dev/null; then + update-alternatives --remove gdm3-theme.css \ + /usr/share/gnome-shell/theme/Cortex/gnome-shell.css 2>/dev/null || true + fi + + # Re-enable default MOTD scripts + if [ -d /etc/update-motd.d ]; then + for f in /etc/update-motd.d/??-*; do + [ -f "$f" ] && chmod +x "$f" 2>/dev/null || true + done + fi + + echo "Cortex Linux branding removed." + ;; + + failed-upgrade) + ;; + + *) + echo "prerm called with unknown argument '$1'" >&2 + exit 1 + ;; +esac + +exit 0 + diff --git a/packages/cortex-branding/debian/rules b/packages/cortex-branding/debian/rules new file mode 100755 index 0000000..a9178fb --- /dev/null +++ b/packages/cortex-branding/debian/rules @@ -0,0 +1,74 @@ +#!/usr/bin/make -f +# +# Cortex Branding Package Build Rules +# +# All branding assets are stored directly in this package directory. +# Build with: dpkg-buildpackage -us -uc -b +# + +export DH_VERBOSE = 1 + +%: + dh $@ + +override_dh_auto_install: + # Install OS identity templates (installed to /etc by postinst to avoid base-files conflict) + install -d $(CURDIR)/debian/cortex-branding/usr/share/cortex/templates + install -m 644 usr/share/cortex/templates/os-release $(CURDIR)/debian/cortex-branding/usr/share/cortex/templates/ + install -m 644 usr/share/cortex/templates/lsb-release $(CURDIR)/debian/cortex-branding/usr/share/cortex/templates/ + install -m 644 usr/share/cortex/templates/issue $(CURDIR)/debian/cortex-branding/usr/share/cortex/templates/ + install -m 644 usr/share/cortex/templates/issue.net $(CURDIR)/debian/cortex-branding/usr/share/cortex/templates/ + + # Install Plymouth theme + install -d $(CURDIR)/debian/cortex-branding/usr/share/plymouth/themes/cortex + cp -r usr/share/plymouth/themes/cortex/* $(CURDIR)/debian/cortex-branding/usr/share/plymouth/themes/cortex/ + + # Install GRUB theme + install -d $(CURDIR)/debian/cortex-branding/boot/grub/themes/cortex + cp -r boot/grub/themes/cortex/* $(CURDIR)/debian/cortex-branding/boot/grub/themes/cortex/ + + # Install wallpapers + install -d $(CURDIR)/debian/cortex-branding/usr/share/backgrounds/cortex + cp -r usr/share/backgrounds/cortex/* $(CURDIR)/debian/cortex-branding/usr/share/backgrounds/cortex/ + install -d $(CURDIR)/debian/cortex-branding/usr/share/gnome-background-properties + cp usr/share/gnome-background-properties/*.xml $(CURDIR)/debian/cortex-branding/usr/share/gnome-background-properties/ 2>/dev/null || true + + # Install MOTD scripts + install -d $(CURDIR)/debian/cortex-branding/etc/update-motd.d + install -m 755 etc/update-motd.d/* $(CURDIR)/debian/cortex-branding/etc/update-motd.d/ + + # Install logos + install -d $(CURDIR)/debian/cortex-branding/usr/share/cortex/logos + cp -r usr/share/cortex/logos/* $(CURDIR)/debian/cortex-branding/usr/share/cortex/logos/ + + # Install dconf profile + install -d $(CURDIR)/debian/cortex-branding/etc/dconf/profile + install -m 644 etc/dconf/profile/user $(CURDIR)/debian/cortex-branding/etc/dconf/profile/ + + # Install GDM dconf configuration + install -d $(CURDIR)/debian/cortex-branding/etc/dconf/db/gdm.d + install -m 644 etc/dconf/db/gdm.d/01-cortex-branding $(CURDIR)/debian/cortex-branding/etc/dconf/db/gdm.d/ + + # Install desktop and terminal dconf configuration + install -d $(CURDIR)/debian/cortex-branding/etc/dconf/db/local.d + install -m 644 etc/dconf/db/local.d/00-cortex-desktop $(CURDIR)/debian/cortex-branding/etc/dconf/db/local.d/ + install -m 644 etc/dconf/db/local.d/01-cortex-terminal $(CURDIR)/debian/cortex-branding/etc/dconf/db/local.d/ + + # Install GSettings schema override + install -d $(CURDIR)/debian/cortex-branding/usr/share/glib-2.0/schemas + install -m 644 usr/share/glib-2.0/schemas/10-cortex-branding.gschema.override $(CURDIR)/debian/cortex-branding/usr/share/glib-2.0/schemas/ + + # Install neofetch configuration + install -d $(CURDIR)/debian/cortex-branding/etc/neofetch + install -m 644 etc/neofetch/config.conf $(CURDIR)/debian/cortex-branding/etc/neofetch/ + install -d $(CURDIR)/debian/cortex-branding/usr/share/neofetch/ascii/distro + install -m 644 usr/share/neofetch/ascii/distro/cortex $(CURDIR)/debian/cortex-branding/usr/share/neofetch/ascii/distro/ + + # Install GDM theme (GNOME Shell login screen) + install -d $(CURDIR)/debian/cortex-branding/usr/share/gnome-shell/theme/Cortex + install -m 644 usr/share/gnome-shell/theme/Cortex/gnome-shell.css $(CURDIR)/debian/cortex-branding/usr/share/gnome-shell/theme/Cortex/ + +override_dh_fixperms: + dh_fixperms + # Ensure MOTD scripts are executable + chmod 755 $(CURDIR)/debian/cortex-branding/etc/update-motd.d/* || true diff --git a/packages/cortex-branding/debian/source/format b/packages/cortex-branding/debian/source/format new file mode 100644 index 0000000..435dd71 --- /dev/null +++ b/packages/cortex-branding/debian/source/format @@ -0,0 +1,2 @@ +3.0 (native) + diff --git a/packages/cortex-branding/etc/dconf/db/gdm.d/01-cortex-branding b/packages/cortex-branding/etc/dconf/db/gdm.d/01-cortex-branding new file mode 100644 index 0000000..e80de65 --- /dev/null +++ b/packages/cortex-branding/etc/dconf/db/gdm.d/01-cortex-branding @@ -0,0 +1,40 @@ +# Cortex Linux GDM Configuration +# +# This file configures GDM branding settings. +# Place in /etc/gdm3/greeter.dconf-defaults + +[org/gnome/login-screen] +# Logo displayed on login screen +logo='/usr/share/cortex/logos/cortex-logo-light.svg' + +# Disable user list for security (optional) +# disable-user-list=true + +# Enable banner message +banner-message-enable=true +banner-message-text='Welcome to Cortex Linux' + +# Disable restart buttons (optional, for kiosks) +# disable-restart-buttons=false + +[org/gnome/desktop/interface] +# Set GTK theme for login screen +gtk-theme='Adwaita-dark' + +# Icon theme +icon-theme='Adwaita' + +# Cursor theme +cursor-theme='Adwaita' + +[org/gnome/desktop/background] +# Login screen background +picture-uri='file:///usr/share/backgrounds/cortex/minimal-dark.png' +picture-options='zoom' +primary-color='#0F0F23' + +[org/gnome/desktop/screensaver] +# Lock screen background +picture-uri='file:///usr/share/backgrounds/cortex/minimal-dark.png' +picture-options='zoom' +primary-color='#0F0F23' diff --git a/packages/cortex-branding/etc/dconf/db/local.d/00-cortex-desktop b/packages/cortex-branding/etc/dconf/db/local.d/00-cortex-desktop new file mode 100644 index 0000000..99d18df --- /dev/null +++ b/packages/cortex-branding/etc/dconf/db/local.d/00-cortex-desktop @@ -0,0 +1,23 @@ +# Cortex Linux GNOME Desktop Branding +# Applied system-wide via dconf + +[org/gnome/desktop/interface] +gtk-theme='Adwaita-dark' +icon-theme='Adwaita' +cursor-theme='Adwaita' +color-scheme='prefer-dark' + +[org/gnome/desktop/background] +picture-uri='file:///usr/share/backgrounds/cortex/minimal-dark.png' +picture-uri-dark='file:///usr/share/backgrounds/cortex/minimal-dark.png' +picture-options='zoom' +primary-color='#0F0F23' + +[org/gnome/desktop/screensaver] +picture-uri='file:///usr/share/backgrounds/cortex/minimal-dark.png' +primary-color='#0F0F23' + +[org/gnome/shell] +welcome-dialog-last-shown-version='9999999999' +favorite-apps=['firefox-esr.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Terminal.desktop', 'org.gnome.Settings.desktop'] + diff --git a/packages/cortex-branding/etc/dconf/db/local.d/01-cortex-terminal b/packages/cortex-branding/etc/dconf/db/local.d/01-cortex-terminal new file mode 100644 index 0000000..65e145d --- /dev/null +++ b/packages/cortex-branding/etc/dconf/db/local.d/01-cortex-terminal @@ -0,0 +1,32 @@ +# Cortex Linux GNOME Terminal Profile +# Import with: dconf load /org/gnome/terminal/ < cortex-terminal.dconf + +[legacy/profiles:/:cortex] +audible-bell=false +background-color='#0D0D0D' +background-transparency-percent=5 +bold-color='#06B6D4' +bold-color-same-as-fg=false +bold-is-bright=true +cursor-background-color='#06B6D4' +cursor-colors-set=true +cursor-foreground-color='#0D0D0D' +cursor-shape='ibeam' +default-size-columns=120 +default-size-rows=32 +font='JetBrains Mono 11' +foreground-color='#E5E5E5' +highlight-background-color='#6B21A8' +highlight-colors-set=true +highlight-foreground-color='#FFFFFF' +palette=['#0D0D0D', '#EF4444', '#22C55E', '#EAB308', '#3B82F6', '#A855F7', '#06B6D4', '#A3A3A3', '#525252', '#F87171', '#4ADE80', '#FACC15', '#60A5FA', '#C084FC', '#22D3EE', '#F5F5F5'] +scroll-on-output=false +scrollback-lines=10000 +use-system-font=false +use-theme-colors=false +use-transparent-background=false +visible-name='Cortex' + +[legacy/profiles:] +default='cortex' +list=['cortex'] diff --git a/packages/cortex-branding/etc/dconf/profile/user b/packages/cortex-branding/etc/dconf/profile/user new file mode 100644 index 0000000..4e6f4fc --- /dev/null +++ b/packages/cortex-branding/etc/dconf/profile/user @@ -0,0 +1,3 @@ +user-db:user +system-db:local + diff --git a/packages/cortex-branding/etc/neofetch/config.conf b/packages/cortex-branding/etc/neofetch/config.conf new file mode 100644 index 0000000..c4e0aff --- /dev/null +++ b/packages/cortex-branding/etc/neofetch/config.conf @@ -0,0 +1,25 @@ +# Cortex Linux Neofetch Configuration + +print_info() { + info title + info underline + info "OS" distro + info "Host" model + info "Kernel" kernel + info "Uptime" uptime + info "Packages" packages + info "Shell" shell + info "Resolution" resolution + info "DE" de + info "WM" wm + info "Terminal" term + info "CPU" cpu + info "GPU" gpu + info "Memory" memory + info cols +} + +# Cortex branding colors (purple/cyan) +colors=(5 6 7 5 6 7) +bold="on" +ascii_distro="cortex" diff --git a/packages/cortex-branding/etc/update-motd.d/00-cortex-banner b/packages/cortex-branding/etc/update-motd.d/00-cortex-banner new file mode 100644 index 0000000..23316b4 --- /dev/null +++ b/packages/cortex-branding/etc/update-motd.d/00-cortex-banner @@ -0,0 +1,27 @@ +#!/bin/bash +# +# Cortex Linux MOTD Banner +# Displays branded welcome message on terminal login +# + +# Colors +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +WHITE='\033[1;37m' +GRAY='\033[0;90m' +RESET='\033[0m' + +# ASCII Art Logo +cat << 'EOF' + + ██████╗ ██████╗ ██████╗ ████████╗███████╗██╗ ██╗ + ██╔════╝██╔═══██╗██╔══██╗╚══██╔══╝██╔════╝╚██╗██╔╝ + ██║ ██║ ██║██████╔╝ ██║ █████╗ ╚███╔╝ + ██║ ██║ ██║██╔══██╗ ██║ ██╔══╝ ██╔██╗ + ╚██████╗╚██████╔╝██║ ██║ ██║ ███████╗██╔╝ ██╗ + ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ + +EOF + +echo -e "${GRAY} L I N U X${RESET}" +echo "" diff --git a/packages/cortex-branding/etc/update-motd.d/10-cortex-sysinfo b/packages/cortex-branding/etc/update-motd.d/10-cortex-sysinfo new file mode 100644 index 0000000..4b627e0 --- /dev/null +++ b/packages/cortex-branding/etc/update-motd.d/10-cortex-sysinfo @@ -0,0 +1,83 @@ +#!/bin/bash +# +# Cortex Linux System Information +# Displays system stats on terminal login +# + +# Colors +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +WHITE='\033[1;37m' +GRAY='\033[0;90m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +RED='\033[0;31m' +RESET='\033[0m' + +# Gather system information +HOSTNAME=$(hostname) +DISTRO=$(grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d'"' -f2 || echo "Cortex Linux") +KERNEL=$(uname -r) +UPTIME=$(uptime -p 2>/dev/null | sed 's/up //' || uptime | awk -F'( |,|:)+' '{print $6"h "$7"m"}') +LOAD=$(cat /proc/loadavg | awk '{print $1" "$2" "$3}') + +# CPU info +CPU_MODEL=$(grep "model name" /proc/cpuinfo 2>/dev/null | head -1 | cut -d':' -f2 | sed 's/^ //' | cut -c1-40) +CPU_CORES=$(nproc 2>/dev/null || echo "?") + +# Memory info +if command -v free &>/dev/null; then + MEM_TOTAL=$(free -h | awk '/^Mem:/ {print $2}') + MEM_USED=$(free -h | awk '/^Mem:/ {print $3}') + MEM_PERCENT=$(free | awk '/^Mem:/ {printf "%.0f", $3/$2*100}') +else + MEM_TOTAL="N/A" + MEM_USED="N/A" + MEM_PERCENT="0" +fi + +# Disk info +if command -v df &>/dev/null; then + DISK_TOTAL=$(df -h / | awk 'NR==2 {print $2}') + DISK_USED=$(df -h / | awk 'NR==2 {print $3}') + DISK_PERCENT=$(df / | awk 'NR==2 {print $5}' | tr -d '%') +else + DISK_TOTAL="N/A" + DISK_USED="N/A" + DISK_PERCENT="0" +fi + +# Network info +IP_ADDR=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "N/A") + +# Users logged in +USERS=$(who 2>/dev/null | wc -l || echo "0") + +# Color based on usage +mem_color() { + if [ "$1" -lt 50 ]; then echo -e "${GREEN}"; + elif [ "$1" -lt 80 ]; then echo -e "${YELLOW}"; + else echo -e "${RED}"; fi +} + +disk_color() { + if [ "$1" -lt 70 ]; then echo -e "${GREEN}"; + elif [ "$1" -lt 90 ]; then echo -e "${YELLOW}"; + else echo -e "${RED}"; fi +} + +# Display +echo -e " ${GRAY}┌──────────────────────────────────────────────────────────────────┐${RESET}" +echo -e " ${GRAY}│${RESET} ${PURPLE}System${RESET} ${WHITE}${HOSTNAME}${RESET}" +echo -e " ${GRAY}│${RESET} ${PURPLE}OS${RESET} ${DISTRO}" +echo -e " ${GRAY}│${RESET} ${PURPLE}Kernel${RESET} ${KERNEL}" +echo -e " ${GRAY}│${RESET} ${PURPLE}Uptime${RESET} ${UPTIME}" +echo -e " ${GRAY}│${RESET} ${PURPLE}Load${RESET} ${LOAD}" +echo -e " ${GRAY}├──────────────────────────────────────────────────────────────────┤${RESET}" +echo -e " ${GRAY}│${RESET} ${CYAN}CPU${RESET} ${CPU_MODEL:-Unknown} (${CPU_CORES} cores)" +echo -e " ${GRAY}│${RESET} ${CYAN}Memory${RESET} $(mem_color $MEM_PERCENT)${MEM_USED}${RESET} / ${MEM_TOTAL} (${MEM_PERCENT}%)" +echo -e " ${GRAY}│${RESET} ${CYAN}Disk${RESET} $(disk_color $DISK_PERCENT)${DISK_USED}${RESET} / ${DISK_TOTAL} (${DISK_PERCENT}%)" +echo -e " ${GRAY}│${RESET} ${CYAN}IP${RESET} ${IP_ADDR}" +echo -e " ${GRAY}│${RESET} ${CYAN}Users${RESET} ${USERS} logged in" +echo -e " ${GRAY}└──────────────────────────────────────────────────────────────────┘${RESET}" +echo "" diff --git a/packages/cortex-branding/etc/update-motd.d/20-cortex-updates b/packages/cortex-branding/etc/update-motd.d/20-cortex-updates new file mode 100644 index 0000000..b3fd97f --- /dev/null +++ b/packages/cortex-branding/etc/update-motd.d/20-cortex-updates @@ -0,0 +1,64 @@ +#!/bin/bash +# +# Cortex Linux Update Notification +# Shows available updates on login (if any) +# + +# Colors +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +YELLOW='\033[0;33m' +RED='\033[0;31m' +GREEN='\033[0;32m' +GRAY='\033[0;90m' +RESET='\033[0m' + +# Check for update-notifier data (created by apt hooks) +UPDATES_FILE="/var/lib/update-notifier/updates-available" +SECURITY_FILE="/var/lib/update-notifier/security-updates-available" +REBOOT_FILE="/var/run/reboot-required" + +# Count updates if apt is available +if command -v apt-get &>/dev/null; then + # Use cached data if available + if [ -f "$UPDATES_FILE" ]; then + UPDATES=$(grep -oP '\d+ updates' "$UPDATES_FILE" 2>/dev/null | grep -oP '\d+' || echo "0") + SECURITY=$(grep -oP '\d+ security' "$UPDATES_FILE" 2>/dev/null | grep -oP '\d+' || echo "0") + else + # Quick check (may not be accurate without apt update) + UPDATES=$(apt list --upgradable 2>/dev/null | grep -c upgradable || echo "0") + SECURITY="?" + fi +else + UPDATES="0" + SECURITY="0" +fi + +# Display update info +if [ "$UPDATES" != "0" ] && [ "$UPDATES" != "" ]; then + echo -e " ${YELLOW}◆${RESET} ${UPDATES} package update(s) available" + if [ "$SECURITY" != "0" ] && [ "$SECURITY" != "?" ] && [ "$SECURITY" != "" ]; then + echo -e " ${RED}◆${RESET} ${SECURITY} security update(s)" + fi + echo -e " ${GRAY} Run: sudo apt update && sudo apt upgrade${RESET}" + echo "" +fi + +# Check if reboot required +if [ -f "$REBOOT_FILE" ]; then + echo -e " ${RED}◆ System restart required${RESET}" + if [ -f "/var/run/reboot-required.pkgs" ]; then + REBOOT_PKGS=$(cat /var/run/reboot-required.pkgs | head -3 | tr '\n' ', ' | sed 's/,$//') + echo -e " ${GRAY} Packages: ${REBOOT_PKGS}${RESET}" + fi + echo -e " ${GRAY} Run: sudo reboot${RESET}" + echo "" +fi + +# Cortex-specific notifications +CORTEX_NOTICE="/opt/cortex/notice" +if [ -f "$CORTEX_NOTICE" ]; then + echo -e " ${CYAN}◆ Cortex Notice:${RESET}" + cat "$CORTEX_NOTICE" | sed 's/^/ /' + echo "" +fi diff --git a/packages/cortex-branding/etc/update-motd.d/99-cortex-footer b/packages/cortex-branding/etc/update-motd.d/99-cortex-footer new file mode 100644 index 0000000..ca365c2 --- /dev/null +++ b/packages/cortex-branding/etc/update-motd.d/99-cortex-footer @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Cortex Linux MOTD Footer +# Shows helpful links and tips +# + +# Colors +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +GRAY='\033[0;90m' +RESET='\033[0m' + +# Random tips +TIPS=( + "Use 'cortex' command for AI-powered shell assistance" + "Run 'cortex-update' to check for Cortex component updates" + "Enable dark mode: gsettings set org.gnome.desktop.interface color-scheme prefer-dark" + "Check security status: sudo lynis audit system" + "View system logs: journalctl -xe" + "Monitor resources: htop or btop" +) + +# Pick random tip +TIP="${TIPS[$RANDOM % ${#TIPS[@]}]}" + +echo -e " ${GRAY}─────────────────────────────────────────────────────────────────────${RESET}" +echo -e " ${PURPLE}Tip:${RESET} ${TIP}" +echo -e " ${GRAY}─────────────────────────────────────────────────────────────────────${RESET}" +echo -e " ${CYAN}Docs:${RESET} https://docs.cortexlinux.com ${CYAN}Support:${RESET} https://cortexlinux.com/support" +echo "" diff --git a/packages/cortex-branding/source/cx-logo-dark.png b/packages/cortex-branding/source/cx-logo-dark.png new file mode 100644 index 0000000..67a322b Binary files /dev/null and b/packages/cortex-branding/source/cx-logo-dark.png differ diff --git a/packages/cortex-branding/source/cx-logo-light.png b/packages/cortex-branding/source/cx-logo-light.png new file mode 100644 index 0000000..a648972 Binary files /dev/null and b/packages/cortex-branding/source/cx-logo-light.png differ diff --git a/packages/cortex-branding/source/cx-logo-primary.png b/packages/cortex-branding/source/cx-logo-primary.png new file mode 100644 index 0000000..a648972 Binary files /dev/null and b/packages/cortex-branding/source/cx-logo-primary.png differ diff --git a/packages/cortex-branding/source/cx-logo-transparent.png b/packages/cortex-branding/source/cx-logo-transparent.png new file mode 100644 index 0000000..049be3a Binary files /dev/null and b/packages/cortex-branding/source/cx-logo-transparent.png differ diff --git a/packages/cortex-branding/source/cx-original.png b/packages/cortex-branding/source/cx-original.png new file mode 100644 index 0000000..a648972 Binary files /dev/null and b/packages/cortex-branding/source/cx-original.png differ diff --git a/packages/cortex-branding/usr/share/backgrounds/cortex/circuit-board.png b/packages/cortex-branding/usr/share/backgrounds/cortex/circuit-board.png new file mode 100644 index 0000000..850d70f Binary files /dev/null and b/packages/cortex-branding/usr/share/backgrounds/cortex/circuit-board.png differ diff --git a/packages/cortex-branding/usr/share/backgrounds/cortex/minimal-dark.png b/packages/cortex-branding/usr/share/backgrounds/cortex/minimal-dark.png new file mode 100644 index 0000000..6baa3cf Binary files /dev/null and b/packages/cortex-branding/usr/share/backgrounds/cortex/minimal-dark.png differ diff --git a/packages/cortex-branding/usr/share/cortex/logos/cortex-icon-128.png b/packages/cortex-branding/usr/share/cortex/logos/cortex-icon-128.png new file mode 100644 index 0000000..8c01a34 Binary files /dev/null and b/packages/cortex-branding/usr/share/cortex/logos/cortex-icon-128.png differ diff --git a/packages/cortex-branding/usr/share/cortex/logos/cortex-logo-light.svg b/packages/cortex-branding/usr/share/cortex/logos/cortex-logo-light.svg new file mode 100644 index 0000000..1ec3a08 --- /dev/null +++ b/packages/cortex-branding/usr/share/cortex/logos/cortex-logo-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/cortex-branding/usr/share/cortex/logos/favicon-32.png b/packages/cortex-branding/usr/share/cortex/logos/favicon-32.png new file mode 100644 index 0000000..0e055d0 Binary files /dev/null and b/packages/cortex-branding/usr/share/cortex/logos/favicon-32.png differ diff --git a/packages/cortex-branding/usr/share/cortex/templates/issue b/packages/cortex-branding/usr/share/cortex/templates/issue new file mode 100644 index 0000000..6e2a95f --- /dev/null +++ b/packages/cortex-branding/usr/share/cortex/templates/issue @@ -0,0 +1,11 @@ + + ██████╗ ██████╗ ██████╗ ████████╗███████╗██╗ ██╗ + ██╔════╝██╔═══██╗██╔══██╗╚══██╔══╝██╔════╝╚██╗██╔╝ + ██║ ██║ ██║██████╔╝ ██║ █████╗ ╚███╔╝ + ██║ ██║ ██║██╔══██╗ ██║ ██╔══╝ ██╔██╗ + ╚██████╗╚██████╔╝██║ ██║ ██║ ███████╗██╔╝ ██╗ + ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ + L I N U X + + Cortex Linux 1.0 (Synapse) \n \l + diff --git a/packages/cortex-branding/usr/share/cortex/templates/issue.net b/packages/cortex-branding/usr/share/cortex/templates/issue.net new file mode 100644 index 0000000..8d4670f --- /dev/null +++ b/packages/cortex-branding/usr/share/cortex/templates/issue.net @@ -0,0 +1 @@ +Cortex Linux 1.0 (Synapse) diff --git a/packages/cortex-branding/usr/share/cortex/templates/lsb-release b/packages/cortex-branding/usr/share/cortex/templates/lsb-release new file mode 100644 index 0000000..24d73bb --- /dev/null +++ b/packages/cortex-branding/usr/share/cortex/templates/lsb-release @@ -0,0 +1,4 @@ +DISTRIB_ID=Cortex +DISTRIB_RELEASE=1.0 +DISTRIB_CODENAME=synapse +DISTRIB_DESCRIPTION="Cortex Linux 1.0 (Synapse)" diff --git a/packages/cortex-branding/usr/share/cortex/templates/os-release b/packages/cortex-branding/usr/share/cortex/templates/os-release new file mode 100644 index 0000000..4c4e301 --- /dev/null +++ b/packages/cortex-branding/usr/share/cortex/templates/os-release @@ -0,0 +1,13 @@ +PRETTY_NAME="Cortex Linux 1.0 (Synapse)" +NAME="Cortex Linux" +VERSION_ID="1.0" +VERSION="1.0 (Synapse)" +VERSION_CODENAME=synapse +ID=cortex +ID_LIKE=debian +HOME_URL="https://cortexlinux.com" +SUPPORT_URL="https://github.com/cortexlinux/cortex-distro/discussions" +BUG_REPORT_URL="https://github.com/cortexlinux/cortex-distro/issues" +PRIVACY_POLICY_URL="https://cortexlinux.com/privacy" +LOGO=cortex-logo +ANSI_COLOR="0;35" diff --git a/packages/cortex-branding/usr/share/glib-2.0/schemas/10-cortex-branding.gschema.override b/packages/cortex-branding/usr/share/glib-2.0/schemas/10-cortex-branding.gschema.override new file mode 100644 index 0000000..c3dcea3 --- /dev/null +++ b/packages/cortex-branding/usr/share/glib-2.0/schemas/10-cortex-branding.gschema.override @@ -0,0 +1,19 @@ +# Cortex Linux GSettings Overrides +# These provide default GNOME settings for Cortex Linux + +[org.gnome.desktop.interface] +gtk-theme='Adwaita-dark' +icon-theme='Adwaita' +cursor-theme='Adwaita' +color-scheme='prefer-dark' + +[org.gnome.desktop.background] +picture-uri='file:///usr/share/backgrounds/cortex/minimal-dark.png' +picture-uri-dark='file:///usr/share/backgrounds/cortex/minimal-dark.png' +picture-options='zoom' +primary-color='#0F0F23' + +[org.gnome.desktop.screensaver] +picture-uri='file:///usr/share/backgrounds/cortex/minimal-dark.png' +primary-color='#0F0F23' + diff --git a/packages/cortex-branding/usr/share/gnome-background-properties/cortex-wallpapers.xml b/packages/cortex-branding/usr/share/gnome-background-properties/cortex-wallpapers.xml new file mode 100644 index 0000000..28b3054 --- /dev/null +++ b/packages/cortex-branding/usr/share/gnome-background-properties/cortex-wallpapers.xml @@ -0,0 +1,23 @@ + + + + + + Cortex Minimal Dark (Default) + /usr/share/backgrounds/cortex/minimal-dark.png + zoom + solid + #0F0F23 + #0F0F23 + + + + Cortex Circuit Board + /usr/share/backgrounds/cortex/circuit-board.png + zoom + solid + #0F0F23 + #0F0F23 + + + diff --git a/packages/cortex-branding/usr/share/gnome-shell/theme/Cortex/gnome-shell.css b/packages/cortex-branding/usr/share/gnome-shell/theme/Cortex/gnome-shell.css new file mode 100644 index 0000000..2bc8791 --- /dev/null +++ b/packages/cortex-branding/usr/share/gnome-shell/theme/Cortex/gnome-shell.css @@ -0,0 +1,167 @@ +/** + * Cortex Linux GDM Theme + * + * Custom styling for the GNOME Display Manager login screen. + * This overrides the default GDM theme with Cortex branding. + */ + +/* Login screen background */ +#lockDialogGroup { + background: #0F0F23 url('resource:///org/gnome/shell/theme/cortex-login-bg.png'); + background-size: cover; + background-position: center; +} + +/* Alternative: Gradient background without image */ +/* +#lockDialogGroup { + background: linear-gradient(135deg, #0F0F23 0%, #1E1B4B 50%, #0F0F23 100%); +} +*/ + +/* Login dialog box */ +.login-dialog { + background-color: rgba(15, 15, 35, 0.85); + border: 1px solid rgba(107, 33, 168, 0.3); + border-radius: 16px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); +} + +/* User avatar */ +.user-widget .user-icon { + border: 2px solid #6B21A8; + border-radius: 50%; + box-shadow: 0 0 20px rgba(107, 33, 168, 0.3); +} + +/* Username label */ +.user-widget .user-widget-label { + color: #E2E8F0; + font-weight: 600; + font-size: 1.2em; +} + +/* Password entry field */ +.login-dialog-prompt-entry { + background-color: rgba(30, 30, 63, 0.8); + border: 1px solid rgba(107, 33, 168, 0.5); + border-radius: 8px; + color: #E2E8F0; + padding: 8px 12px; +} + +.login-dialog-prompt-entry:focus { + border-color: #06B6D4; + box-shadow: 0 0 8px rgba(6, 182, 212, 0.3); +} + +/* Login button */ +.modal-dialog-button { + background-color: #6B21A8; + border: none; + border-radius: 8px; + color: #FFFFFF; + font-weight: 600; + padding: 10px 24px; + transition: all 0.2s ease; +} + +.modal-dialog-button:hover { + background-color: #7C3AED; + box-shadow: 0 4px 12px rgba(107, 33, 168, 0.4); +} + +.modal-dialog-button:active { + background-color: #5B21B6; +} + +/* Session/power buttons */ +.login-dialog-button-box .login-dialog-button { + background-color: transparent; + border: 1px solid rgba(148, 163, 184, 0.3); + border-radius: 6px; + color: #94A3B8; +} + +.login-dialog-button-box .login-dialog-button:hover { + background-color: rgba(107, 33, 168, 0.2); + border-color: #6B21A8; + color: #E2E8F0; +} + +/* Message/error labels */ +.login-dialog-message { + color: #94A3B8; + font-size: 0.9em; +} + +.login-dialog-message-warning { + color: #FBBF24; +} + +.login-dialog-message-hint { + color: #64748B; +} + +/* Banner message (optional) */ +.login-dialog-banner { + background-color: rgba(6, 182, 212, 0.1); + border-left: 3px solid #06B6D4; + color: #E2E8F0; + padding: 8px 12px; + margin-bottom: 12px; + border-radius: 4px; +} + +/* Clock styling */ +.clock-display { + color: #E2E8F0; + font-size: 4em; + font-weight: 300; + text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5); +} + +.clock-display .clock-weekday, +.clock-display .clock-date { + color: #94A3B8; + font-size: 0.35em; + font-weight: 400; +} + +/* Panel/top bar on login screen */ +#panel { + background-color: transparent; +} + +/* User list (multi-user) */ +.user-list-item { + background-color: rgba(30, 30, 63, 0.6); + border-radius: 8px; + margin: 4px; + padding: 8px; +} + +.user-list-item:hover { + background-color: rgba(107, 33, 168, 0.3); +} + +.user-list-item:selected { + background-color: rgba(107, 33, 168, 0.5); + border: 1px solid #6B21A8; +} + +/* Fingerprint prompt */ +.login-dialog-prompt-fingerprint-message { + color: #06B6D4; + font-size: 0.85em; +} + +/* Logo/branding area */ +.login-dialog-logo { + background-image: url('resource:///org/gnome/shell/theme/cortex-logo.svg'); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + min-height: 80px; + min-width: 200px; +} diff --git a/packages/cortex-branding/usr/share/neofetch/ascii/distro/cortex b/packages/cortex-branding/usr/share/neofetch/ascii/distro/cortex new file mode 100644 index 0000000..e7c92f8 --- /dev/null +++ b/packages/cortex-branding/usr/share/neofetch/ascii/distro/cortex @@ -0,0 +1,10 @@ +${c1} +${c1} ██████╗ ██████╗ ██████╗ ████████╗███████╗██╗ ██╗ +${c1} ██╔════╝██╔═══██╗██╔══██╗╚══██╔══╝██╔════╝╚██╗██╔╝ +${c2} ██║ ██║ ██║██████╔╝ ██║ █████╗ ╚███╔╝ +${c2} ██║ ██║ ██║██╔══██╗ ██║ ██╔══╝ ██╔██╗ +${c1} ╚██████╗╚██████╔╝██║ ██║ ██║ ███████╗██╔╝ ██╗ +${c1} ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ +${c2} +${c2} L I N U X + diff --git a/packages/cortex-branding/usr/share/plymouth/themes/cortex/bullet.png b/packages/cortex-branding/usr/share/plymouth/themes/cortex/bullet.png new file mode 100644 index 0000000..55eda59 Binary files /dev/null and b/packages/cortex-branding/usr/share/plymouth/themes/cortex/bullet.png differ diff --git a/packages/cortex-branding/usr/share/plymouth/themes/cortex/cortex.plymouth b/packages/cortex-branding/usr/share/plymouth/themes/cortex/cortex.plymouth new file mode 100644 index 0000000..50431f6 --- /dev/null +++ b/packages/cortex-branding/usr/share/plymouth/themes/cortex/cortex.plymouth @@ -0,0 +1,8 @@ +[Plymouth Theme] +Name=Cortex Linux +Description=Cortex Linux boot splash with neural network animation +ModuleName=script + +[script] +ImageDir=/usr/share/plymouth/themes/cortex +ScriptFile=/usr/share/plymouth/themes/cortex/cortex.script diff --git a/packages/cortex-branding/usr/share/plymouth/themes/cortex/cortex.script b/packages/cortex-branding/usr/share/plymouth/themes/cortex/cortex.script new file mode 100644 index 0000000..3697278 --- /dev/null +++ b/packages/cortex-branding/usr/share/plymouth/themes/cortex/cortex.script @@ -0,0 +1,151 @@ +/** + * Cortex Linux Plymouth Theme + * + * Minimal design - CX logo centered on pure black background + * with three animated loading dots at the bottom. + */ + +// Pure black background +Window.SetBackgroundTopColor(0, 0, 0); +Window.SetBackgroundBottomColor(0, 0, 0); + +// Screen dimensions +screen_width = Window.GetWidth(); +screen_height = Window.GetHeight(); +screen_x = Window.GetX(); +screen_y = Window.GetY(); + +// Load and center the CX logo +logo.image = Image("logo.png"); +logo.width = logo.image.GetWidth(); +logo.height = logo.image.GetHeight(); +logo.x = screen_x + screen_width / 2 - logo.width / 2; +logo.y = screen_y + screen_height / 2 - logo.height / 2; +logo.sprite = Sprite(logo.image); +logo.sprite.SetPosition(logo.x, logo.y, 10); +logo.sprite.SetOpacity(1); + +// ============================================ +// THREE DOTS LOADING INDICATOR +// ============================================ + +// Load dot images +dot_on = Image("dot-on.png"); +dot_off = Image("dot-off.png"); + +// Create 3 dot sprites +dot_count = 3; +spacing = 30; // pixels between dots +dot_y = screen_y + screen_height - 80; // 80px from bottom + +for (i = 0; i < dot_count; i++) { + dots[i].sprite = Sprite(dot_off); + dots[i].x = screen_x + screen_width / 2 + (i - 1) * spacing - dot_off.GetWidth() / 2; + dots[i].sprite.SetPosition(dots[i].x, dot_y, 10); + dots[i].sprite.SetOpacity(0.4); +} + +// Animation state +global.dot_frame = 0; +global.dot_timer = 0; + +// Animate the dots - each dot lights up in sequence +fun animate_dots() { + global.dot_timer++; + + // Change active dot every ~15 frames (roughly 0.25 seconds at 60fps) + if (global.dot_timer >= 15) { + global.dot_timer = 0; + global.dot_frame++; + if (global.dot_frame >= dot_count) { + global.dot_frame = 0; + } + } + + // Update dot appearances + for (i = 0; i < dot_count; i++) { + if (i == global.dot_frame) { + dots[i].sprite.SetImage(dot_on); + dots[i].sprite.SetOpacity(1.0); + } else { + dots[i].sprite.SetImage(dot_off); + dots[i].sprite.SetOpacity(0.4); + } + } +} + +// Refresh callback - called continuously for animation +fun refresh_callback() { + animate_dots(); +} +Plymouth.SetRefreshFunction(refresh_callback); + +// Progress callback +fun progress_callback(duration, progress) { + animate_dots(); +} +Plymouth.SetBootProgressFunction(progress_callback); + +// ============================================ +// PASSWORD PROMPT +// ============================================ + +fun password_dialogue_setup(title, bullet) { + local.entry; + local.bullet_image; + + bullet_image = Image(bullet); + entry.image = Image("entry.png"); + entry.sprite = Sprite(entry.image); + entry.x = screen_x + screen_width / 2 - entry.image.GetWidth() / 2; + entry.y = screen_y + screen_height / 2 + 200; + entry.sprite.SetPosition(entry.x, entry.y, 10); + + global.password_entry = entry; + global.password_bullet = bullet_image; + global.password_bullets = []; + + prompt.image = Image.Text(title, 0.8, 0.8, 0.9, 1, "Sans 14"); + prompt.sprite = Sprite(prompt.image); + prompt.x = screen_x + screen_width / 2 - prompt.image.GetWidth() / 2; + prompt.y = entry.y - prompt.image.GetHeight() - 10; + prompt.sprite.SetPosition(prompt.x, prompt.y, 10); + + global.password_prompt = prompt; +} + +fun password_dialogue_opacity(opacity) { + global.password_entry.sprite.SetOpacity(opacity); + global.password_prompt.sprite.SetOpacity(opacity); + for (i = 0; global.password_bullets[i]; i++) { + global.password_bullets[i].sprite.SetOpacity(opacity); + } +} + +Plymouth.SetDisplayPasswordFunction(password_dialogue_setup); + +fun display_normal_callback() { + password_dialogue_opacity(0); +} +Plymouth.SetDisplayNormalFunction(display_normal_callback); + +// ============================================ +// MESSAGES & QUIT +// ============================================ + +fun message_callback(text) { + message.image = Image.Text(text, 0.6, 0.6, 0.7, 1, "Sans 11"); + message.sprite = Sprite(message.image); + message.x = screen_x + screen_width / 2 - message.image.GetWidth() / 2; + message.y = screen_y + screen_height - 50; + message.sprite.SetPosition(message.x, message.y, 10); +} +Plymouth.SetMessageFunction(message_callback); + +fun quit_callback() { + logo.sprite.SetOpacity(0); + for (i = 0; i < dot_count; i++) { + dots[i].sprite.SetOpacity(0); + } +} +Plymouth.SetQuitFunction(quit_callback); diff --git a/packages/cortex-branding/usr/share/plymouth/themes/cortex/dot-off.png b/packages/cortex-branding/usr/share/plymouth/themes/cortex/dot-off.png new file mode 100644 index 0000000..5b2ec11 Binary files /dev/null and b/packages/cortex-branding/usr/share/plymouth/themes/cortex/dot-off.png differ diff --git a/packages/cortex-branding/usr/share/plymouth/themes/cortex/dot-on.png b/packages/cortex-branding/usr/share/plymouth/themes/cortex/dot-on.png new file mode 100644 index 0000000..e2a3a69 Binary files /dev/null and b/packages/cortex-branding/usr/share/plymouth/themes/cortex/dot-on.png differ diff --git a/packages/cortex-branding/usr/share/plymouth/themes/cortex/entry.png b/packages/cortex-branding/usr/share/plymouth/themes/cortex/entry.png new file mode 100644 index 0000000..6d38687 Binary files /dev/null and b/packages/cortex-branding/usr/share/plymouth/themes/cortex/entry.png differ diff --git a/packages/cortex-branding/usr/share/plymouth/themes/cortex/logo.png b/packages/cortex-branding/usr/share/plymouth/themes/cortex/logo.png new file mode 100644 index 0000000..b01c496 Binary files /dev/null and b/packages/cortex-branding/usr/share/plymouth/themes/cortex/logo.png differ diff --git a/packages/cortex-core/DEBIAN/control b/packages/cortex-core/DEBIAN/control new file mode 100644 index 0000000..9971891 --- /dev/null +++ b/packages/cortex-core/DEBIAN/control @@ -0,0 +1,20 @@ +Package: cortex-core +Version: 0.1.0 +Section: metapackages +Priority: optional +Architecture: all +Depends: cortex-archive-keyring, cortex-upgrade, cortex-gpu, cortex-verify +Recommends: neofetch, htop, curl, wget, git +Suggests: cortex-full, cortex-secops +Maintainer: Cortex Linux Team +Homepage: https://cortexlinux.com +Description: Cortex Linux core meta-package with CLI tools + This meta-package installs the core Cortex Linux components: + . + - cortex-upgrade: Safe system upgrades with LVM/Btrfs/ZFS snapshot rollback + - cortex-gpu: GPU detection, NVIDIA/AMD driver enablement, Secure Boot MOK setup + - cortex-verify: Offline integrity verification + - cortex-archive-keyring: GPG keyring for Cortex APT repository trust + . + Install this package to get the essential Cortex Linux tools on any + Debian or Ubuntu system. diff --git a/packages/cortex-full/DEBIAN/control b/packages/cortex-full/DEBIAN/control new file mode 100644 index 0000000..8883142 --- /dev/null +++ b/packages/cortex-full/DEBIAN/control @@ -0,0 +1,40 @@ +Package: cortex-full +Version: 0.1.0 +Section: metapackages +Priority: optional +Architecture: all +Depends: cortex-core, + cortex-branding, + task-gnome-desktop, + gnome-tweaks, + flatpak, + gnome-software-plugin-flatpak +Recommends: docker.io, + docker-compose, + build-essential, + python3-pip, + python3-venv, + nodejs, + npm, + golang, + rustc, + cargo, + firefox-esr, + libreoffice, + gimp, + vlc, + thunderbird +Suggests: cortex-secops, cortex-llm +Maintainer: Cortex Linux Team +Homepage: https://cortexlinux.com +Description: Cortex Linux full installation meta-package + This meta-package installs the complete Cortex Linux desktop environment + with development tools and productivity applications: + . + - GNOME Desktop Environment with Cortex branding + - Development tools: Python, Node.js, Go, Rust, Docker + - Productivity: Firefox, LibreOffice, Thunderbird + - Media: GIMP, VLC + - Flatpak support for additional applications + . + This is the recommended package for workstations and development machines. diff --git a/packages/cortex-secops/DEBIAN/control b/packages/cortex-secops/DEBIAN/control new file mode 100644 index 0000000..d8dbcff --- /dev/null +++ b/packages/cortex-secops/DEBIAN/control @@ -0,0 +1,55 @@ +Package: cortex-secops +Version: 0.1.0 +Section: metapackages +Priority: optional +Architecture: all +Depends: cortex-core, + apparmor, + apparmor-utils, + apparmor-profiles, + apparmor-profiles-extra, + auditd, + audispd-plugins, + aide, + aide-common, + rkhunter, + chkrootkit, + fail2ban, + ufw, + cryptsetup, + cryptsetup-initramfs +Recommends: clamav, + clamav-daemon, + clamav-freshclam, + lynis, + tiger, + tripwire, + ossec-hids, + psad, + logwatch, + acct, + sysstat, + arpwatch, + needrestart, + debsums, + apt-listbugs, + apt-listchanges, + unattended-upgrades +Suggests: cortex-full +Maintainer: Cortex Linux Team +Homepage: https://cortexlinux.com +Description: Cortex Linux security operations meta-package + This meta-package installs security-hardened tools for security operations: + . + - Mandatory Access Control: AppArmor with profiles + - Audit: auditd with plugins for compliance logging + - File Integrity: AIDE, rkhunter, chkrootkit, debsums + - Intrusion Detection: fail2ban, OSSEC, psad + - Antivirus: ClamAV with freshclam updates + - Security Scanning: Lynis, Tiger + - Encryption: cryptsetup for LUKS full disk encryption + - Firewall: UFW (Uncomplicated Firewall) + - Automatic Security Updates: unattended-upgrades + . + Recommended for security-critical deployments requiring compliance + (PCI-DSS, HIPAA, SOC2) and hardened configurations. diff --git a/repository/scripts/repo-manage.sh b/repository/scripts/repo-manage.sh index c0570d4..3167f9c 100755 --- a/repository/scripts/repo-manage.sh +++ b/repository/scripts/repo-manage.sh @@ -135,7 +135,11 @@ cmd_publish() { # Generate Packages file log "Generating Packages for ${suite}/${arch}..." - (cd "${REPO_DIR}" && dpkg-scanpackages --arch "$arch" pool/main > "${arch_dir}/Packages" 2>/dev/null || true) + if [ -d "${REPO_DIR}/pool/main" ]; then + (cd "${REPO_DIR}" && dpkg-scanpackages --arch "$arch" pool/main > "${arch_dir}/Packages") + else + touch "${arch_dir}/Packages" + fi gzip -9 -k -f "${arch_dir}/Packages" xz -9 -k -f "${arch_dir}/Packages" diff --git a/scripts/build.sh b/scripts/build.sh index a7cecdd..8c38101 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,18 +1,31 @@ #!/bin/bash -# Cortex Linux Master Build Script -# One-command ISO build with all dependencies +# Cortex Linux Build Script +# Called by Makefile to handle all build operations # Copyright 2025 AI Venture Holdings LLC # SPDX-License-Identifier: Apache-2.0 -set -e +set -euo pipefail + +# ============================================================================= +# Configuration +# ============================================================================= SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="${SCRIPT_DIR}/.." -# Configuration -VERSION="${CORTEX_VERSION:-0.1.0}" -ARCH="${CORTEX_ARCH:-amd64}" -BUILD_TYPE="${1:-offline}" # netinst or offline +# Directories +BUILD_DIR="${PROJECT_ROOT}/build" +OUTPUT_DIR="${PROJECT_ROOT}/output" +ISO_DIR="${PROJECT_ROOT}/iso" +PRESEED_DIR="${ISO_DIR}/preseed" +PROVISION_DIR="${ISO_DIR}/provisioning" +PACKAGES_DIR="${PROJECT_ROOT}/packages" + +# Defaults +ARCH="${ARCH:-amd64}" +DEBIAN_VERSION="${DEBIAN_VERSION:-bookworm}" +ISO_NAME="${ISO_NAME:-cortex-linux}" +ISO_VERSION="${ISO_VERSION:-$(date +%Y%m%d)}" # Colors RED='\033[0;31m' @@ -21,317 +34,980 @@ YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' -log() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $*"; } -warn() { echo -e "${YELLOW}[$(date '+%H:%M:%S')]${NC} $*"; } -error() { echo -e "${RED}[$(date '+%H:%M:%S')]${NC} $*" >&2; } -header() { echo -e "\n${BLUE}========================================${NC}\n${BLUE}$*${NC}\n${BLUE}========================================${NC}\n"; } +# ============================================================================= +# Logging +# ============================================================================= -usage() { - cat << EOF -Cortex Linux Build Script +log() { echo -e "${GREEN}[BUILD]${NC} $*"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } +header() { echo -e "\n${BLUE}=== $* ===${NC}\n"; } +pass() { echo -e "${GREEN}[PASS]${NC} $*"; } +fail() { echo -e "${RED}[FAIL]${NC} $*"; } -Usage: $(basename "$0") [build-type] [options] +# ============================================================================= +# Helper Functions +# ============================================================================= -Build Types: - netinst Build minimal network installer ISO (~500MB) - offline Build full offline ISO with package pool (~2-4GB) - packages Build Debian packages only - all Build both ISOs +copy_if_exists() { + local src="$1" + local dest="$2" + if [ -e "$src" ]; then + cp -r "$src" "$dest" + return 0 + fi + return 1 +} -Options: - -v, --version Set version (default: 0.1.0) - -a, --arch Set architecture (default: amd64) - -c, --clean Clean before building - -h, --help Show this help +copy_glob_if_exists() { + local pattern="$1" + local dest="$2" + # shellcheck disable=SC2086 + if ls $pattern 1>/dev/null 2>&1; then + cp $pattern "$dest" + return 0 + fi + return 1 +} -Examples: - $(basename "$0") offline - $(basename "$0") netinst --clean - $(basename "$0") all --version 0.2.0 - -Requirements: - - Debian 12+ or Ubuntu 24.04+ build host - - Root/sudo access for live-build - - ~10GB free disk space - - Internet connection (for package downloads) -EOF +check_command() { + local cmd="$1" + local pkg="${2:-$1}" + if command -v "$cmd" &>/dev/null; then + log "$cmd: OK" + return 0 + else + error "$cmd not installed. Install with: sudo apt install $pkg" + return 1 + fi } -check_requirements() { - header "Checking Requirements" - - local missing=0 - - # Check OS - if [ -f /etc/debian_version ]; then - log "Debian-based OS detected" +# ============================================================================= +# Dependency Checking +# ============================================================================= + +cmd_check_deps() { + local failed=0 + + header "Checking build dependencies" + + # Required dependencies + check_command lb live-build || failed=1 + check_command gpg gnupg || failed=1 + check_command python3 python3 || failed=1 + + # Check live-build version + if command -v lb &>/dev/null; then + local lb_version + lb_version=$(dpkg-query -W -f='${Version}' live-build 2>/dev/null || echo "0") + if dpkg --compare-versions "$lb_version" lt "1:20210814"; then + warn "live-build version $lb_version may be too old. Recommended: >= 1:20210814" + else + log "live-build version: $lb_version" + fi + fi + + # Check Python version + if command -v python3 &>/dev/null; then + if python3 -c "import sys; sys.exit(0 if sys.version_info >= (3, 11) else 1)" 2>/dev/null; then + log "Python version: $(python3 --version 2>&1 | cut -d' ' -f2)" + else + warn "Python 3.11+ recommended (found: $(python3 --version 2>&1 | cut -d' ' -f2))" + fi + fi + + # Optional dependencies + echo "" + log "Checking optional dependencies..." + + if command -v shellcheck &>/dev/null; then + log "shellcheck: OK" else - warn "Non-Debian OS - build may not work correctly" + warn "shellcheck not installed (optional, for linting)" fi - - # Check for required commands - local required_cmds=( - "dpkg-buildpackage" - "lb" - "debootstrap" - "xorriso" - "mksquashfs" + + if command -v convert &>/dev/null; then + log "ImageMagick: OK" + else + warn "ImageMagick not installed (optional, for GRUB theme images)" + fi + + if command -v dpkg-deb &>/dev/null; then + log "dpkg-deb: OK" + else + warn "dpkg-deb not installed (needed for branding-package)" + fi + + echo "" + if [ $failed -eq 0 ]; then + log "All required dependencies found." + return 0 + else + error "Missing required dependencies." + return 1 + fi +} + +# ============================================================================= +# Validation Functions +# ============================================================================= + +validate_preseed() { + log "Validating preseed files..." + local found=0 + local warnings=0 + + for dir in "$PRESEED_DIR" "$PRESEED_DIR/profiles" "$PRESEED_DIR/partitioning"; do + if [ -d "$dir" ]; then + for f in "$dir"/*.preseed; do + if [ -f "$f" ]; then + found=$((found + 1)) + if grep -qE '^[^#]*[[:space:]]$' "$f"; then + warn " $f: trailing whitespace" + warnings=$((warnings + 1)) + fi + fi + done + fi + done + + if [ $found -eq 0 ]; then + warn "No preseed files found" + else + log "Checked $found preseed files ($warnings warnings)" + fi +} + +validate_provision() { + log "Validating provisioning scripts..." + local errors=0 + + if [ -f "${PROVISION_DIR}/first-boot.sh" ]; then + if bash -n "${PROVISION_DIR}/first-boot.sh"; then + pass "first-boot.sh: syntax OK" + else + fail "first-boot.sh: SYNTAX ERROR" + errors=$((errors + 1)) + fi + else + warn "first-boot.sh not found" + fi + + for script in "${PROVISION_DIR}"/*.sh; do + if [ -f "$script" ] && [ "$(basename "$script")" != "first-boot.sh" ]; then + if bash -n "$script"; then + pass "$(basename "$script"): syntax OK" + else + fail "$(basename "$script"): SYNTAX ERROR" + errors=$((errors + 1)) + fi + fi + done + + return $errors +} + +validate_hooks() { + log "Validating live-build hooks..." + local hooks_dir="${ISO_DIR}/live-build/config/hooks/live" + local errors=0 + + if [ -d "$hooks_dir" ]; then + for hook in "$hooks_dir"/*.hook.chroot "$hooks_dir"/*.hook.binary; do + if [ -f "$hook" ]; then + if bash -n "$hook"; then + pass "$(basename "$hook"): syntax OK" + else + fail "$(basename "$hook"): SYNTAX ERROR" + errors=$((errors + 1)) + fi + fi + done + else + warn "Hooks directory not found" + fi + + return $errors +} + +run_shellcheck() { + log "Running shellcheck..." + + if ! command -v shellcheck &>/dev/null; then + warn "shellcheck not installed, skipping" + return 0 + fi + + local errors=0 + + # Check provisioning scripts + for script in "${PROVISION_DIR}"/*.sh; do + if [ -f "$script" ]; then + if shellcheck "$script" 2>/dev/null; then + pass "$(basename "$script"): OK" + else + fail "$(basename "$script"): issues found" + errors=$((errors + 1)) + fi + fi + done + + # Check build script itself + if shellcheck "${SCRIPT_DIR}/build.sh" 2>/dev/null; then + pass "build.sh: OK" + else + fail "build.sh: issues found" + errors=$((errors + 1)) + fi + + return $errors +} + +cmd_validate() { + local mode="${1:-all}" + local errors=0 + + header "Validation" + + case "$mode" in + preseed) + validate_preseed + ;; + provision) + validate_provision || errors=$((errors + $?)) + ;; + hooks) + validate_hooks || errors=$((errors + $?)) + ;; + lint) + run_shellcheck || errors=$((errors + $?)) + ;; + all) + validate_preseed + echo "" + validate_provision || errors=$((errors + $?)) + echo "" + validate_hooks || errors=$((errors + $?)) + echo "" + run_shellcheck || errors=$((errors + $?)) + ;; + *) + error "Unknown validation mode: $mode" + return 1 + ;; + esac + + echo "" + if [ $errors -eq 0 ]; then + log "All validation checks passed." + else + error "Validation completed with errors" + return 1 + fi +} + +# ============================================================================= +# Test Functions +# ============================================================================= + +cmd_test() { + local errors=0 + + header "Running Test Suite" + + # Test preseed file exists + log "Testing preseed files..." + if [ -f "${PRESEED_DIR}/cortex.preseed" ]; then + pass "cortex.preseed: found" + else + fail "cortex.preseed: MISSING" + errors=$((errors + 1)) + fi + + echo "" + + # Test provisioning scripts + log "Testing provisioning scripts..." + if [ -f "${PROVISION_DIR}/first-boot.sh" ]; then + if bash -n "${PROVISION_DIR}/first-boot.sh"; then + pass "first-boot.sh: syntax OK" + else + fail "first-boot.sh: SYNTAX ERROR" + errors=$((errors + 1)) + fi + else + fail "first-boot.sh: NOT FOUND" + errors=$((errors + 1)) + fi + + echo "" + + # Test branding package assets + log "Testing branding package assets..." + local pkg_branding="${PACKAGES_DIR}/cortex-branding" + local required_files=( + "boot/grub/themes/cortex/theme.txt" + "usr/share/cortex/templates/os-release" + "usr/share/cortex/templates/lsb-release" + "usr/share/plymouth/themes/cortex/cortex.plymouth" ) - - for cmd in "${required_cmds[@]}"; do - if command -v "$cmd" &>/dev/null; then - log "Found: $cmd" + + for file in "${required_files[@]}"; do + if [ -f "${pkg_branding}/${file}" ]; then + pass "${file}: found" else - error "Missing: $cmd" - ((missing++)) + fail "${file}: MISSING" + errors=$((errors + 1)) fi done - - if [ $missing -gt 0 ]; then - error "" - error "$missing required tools missing. Install with:" - error " sudo apt-get install live-build debootstrap squashfs-tools xorriso dpkg-dev devscripts" + + echo "" + + # Test hooks + log "Testing live-build hooks..." + local hooks_dir="${ISO_DIR}/live-build/config/hooks/live" + for hook in "$hooks_dir"/*.hook.chroot; do + if [ -f "$hook" ]; then + if bash -n "$hook"; then + pass "$(basename "$hook"): syntax OK" + else + fail "$(basename "$hook"): SYNTAX ERROR" + errors=$((errors + 1)) + fi + fi + done + + echo "" + + # Test package control files (debian/ source format) + log "Testing package control files..." + local pkg_dir="${PACKAGES_DIR}/cortex-branding/debian" + for file in control postinst prerm rules; do + if [ -f "${pkg_dir}/${file}" ]; then + pass "debian/${file}: found" + if [[ "$file" == "postinst" || "$file" == "prerm" ]]; then + if bash -n "${pkg_dir}/${file}"; then + pass "debian/${file}: syntax OK" + else + fail "debian/${file}: SYNTAX ERROR" + errors=$((errors + 1)) + fi + fi + else + fail "debian/${file}: MISSING" + errors=$((errors + 1)) + fi + done + + echo "" + echo "========================" + if [ $errors -eq 0 ]; then + log "All tests passed!" + return 0 + else + error "Tests completed with ${errors} error(s)" + return 1 + fi +} + +# ============================================================================= +# ISO Build Functions +# ============================================================================= + +prepare_build_dir() { + header "Preparing build directory" + + mkdir -p "${BUILD_DIR}/config/package-lists" + mkdir -p "${BUILD_DIR}/config/hooks/live" + + # Copy package lists + if copy_glob_if_exists "${ISO_DIR}/live-build/config/package-lists/*.list.chroot" "${BUILD_DIR}/config/package-lists/"; then + log "Copied package lists" + fi + + # Copy hooks + if [ -d "${ISO_DIR}/live-build/config/hooks" ]; then + cp -r "${ISO_DIR}/live-build/config/hooks" "${BUILD_DIR}/config/" + log "Copied hooks" + fi + + # Copy includes.chroot (use -rL to follow symlinks and copy actual content) + if [ -d "${ISO_DIR}/live-build/config/includes.chroot" ]; then + # Remove target first to avoid conflicts with symlinks + rm -rf "${BUILD_DIR}/config/includes.chroot" + cp -rL "${ISO_DIR}/live-build/config/includes.chroot" "${BUILD_DIR}/config/" + log "Copied includes.chroot (symlinks dereferenced)" + fi + + # Copy includes.binary + if [ -d "${ISO_DIR}/live-build/config/includes.binary" ]; then + cp -r "${ISO_DIR}/live-build/config/includes.binary" "${BUILD_DIR}/config/" + log "Copied includes.binary" + fi + + # Copy bootloaders + if [ -d "${ISO_DIR}/live-build/config/bootloaders" ]; then + cp -r "${ISO_DIR}/live-build/config/bootloaders" "${BUILD_DIR}/config/" + log "Copied bootloaders" + fi + + # Copy local .deb packages (packages.chroot) + if [ -d "${ISO_DIR}/live-build/config/packages.chroot" ]; then + mkdir -p "${BUILD_DIR}/config/packages.chroot" + # Copy any existing .deb files (excluding .gitkeep) + if ls "${ISO_DIR}/live-build/config/packages.chroot"/*.deb 1>/dev/null 2>&1; then + cp "${ISO_DIR}/live-build/config/packages.chroot"/*.deb "${BUILD_DIR}/config/packages.chroot/" + log "Copied local .deb packages from packages.chroot" + fi + fi +} + +copy_grub_theme() { + local theme_dest="${BUILD_DIR}/config/bootloaders/grub-pc/live-theme" + local theme_src="${PACKAGES_DIR}/cortex-branding/boot/grub/themes/cortex" + + header "Copying GRUB theme from package" + + mkdir -p "$theme_dest" + + # Copy all theme files from package + if [ -d "$theme_src" ]; then + cp -r "$theme_src"/* "$theme_dest/" + log "Copied GRUB theme files" + else + error "GRUB theme not found in ${theme_src}" exit 1 fi - - # Check disk space - local free_space - free_space=$(df -BG "${PROJECT_ROOT}" | tail -1 | awk '{print $4}' | tr -d 'G') - if [ "$free_space" -lt 10 ]; then - warn "Low disk space: ${free_space}GB free (recommend 10GB+)" + + # Convert background to 8-bit for GRUB compatibility + if command -v convert &>/dev/null && [ -f "${theme_dest}/background.png" ]; then + convert "${theme_dest}/background.png" -depth 8 -type TrueColor \ + "PNG24:${theme_dest}/background.png" + log "Converted background.png to 8-bit for GRUB" + fi +} + +configure_live_build() { + header "Configuring live-build" + + cd "$BUILD_DIR" + + # Use lz4 compression for faster builds (CI), xz for release builds + # lz4: ~2-3 min vs xz: ~20 min, but ISO is ~20% larger + local compression="${SQUASHFS_COMP:-lz4}" + + # Check if apt-cacher-ng is running locally for package caching + local mirror_bootstrap="http://deb.debian.org/debian" + local mirror_chroot="http://deb.debian.org/debian" + local mirror_binary="http://deb.debian.org/debian" + + if curl -s --connect-timeout 2 http://localhost:3142 >/dev/null 2>&1; then + log "apt-cacher-ng detected, using local cache proxy" + mirror_bootstrap="http://localhost:3142/deb.debian.org/debian" + mirror_chroot="http://localhost:3142/deb.debian.org/debian" + mirror_binary="http://deb.debian.org/debian" # Keep binary mirror direct for ISO else - log "Disk space OK: ${free_space}GB free" + warn "apt-cacher-ng not running, using direct mirrors (slower)" fi - - log "All requirements satisfied" + + lb config \ + --distribution "$DEBIAN_VERSION" \ + --archive-areas "main contrib non-free non-free-firmware" \ + --architectures "$ARCH" \ + --binary-images iso-hybrid \ + --bootappend-live "boot=live components username=cortex quiet splash plymouth.ignore-serial-consoles preseed/file=/cdrom/preseed/cortex.preseed" \ + --debian-installer live \ + --debian-installer-gui false \ + --iso-application "Cortex Linux" \ + --iso-publisher "AI Venture Holdings LLC" \ + --iso-volume "CORTEX_LINUX" \ + --mirror-bootstrap "$mirror_bootstrap" \ + --mirror-chroot "$mirror_chroot" \ + --mirror-binary "$mirror_binary" \ + --cache true \ + --cache-packages true \ + --cache-indices true \ + --cache-stages bootstrap \ + --chroot-squashfs-compression-type "$compression" + + log "Live-build configured (compression: ${compression})" } -install_dependencies() { - header "Installing Build Dependencies" - - sudo apt-get update - sudo apt-get install -y \ - live-build \ - debootstrap \ - squashfs-tools \ - xorriso \ - isolinux \ - syslinux-efi \ - grub-pc-bin \ - grub-efi-amd64-bin \ - mtools \ - dosfstools \ - dpkg-dev \ - devscripts \ - debhelper \ - fakeroot \ - gnupg - - log "Dependencies installed" +copy_preseed_files() { + local preseed_dest="${BUILD_DIR}/config/includes.binary/preseed" + + header "Copying preseed and provisioning files" + + mkdir -p "$preseed_dest" + mkdir -p "${BUILD_DIR}/config/includes.binary/provisioning" + + # Copy preseed files + if copy_glob_if_exists "${PRESEED_DIR}/*.preseed" "$preseed_dest/"; then + log "Copied preseed files" + fi + + # Copy provisioning files (use -r for directories) + if [ -d "$PROVISION_DIR" ]; then + cp -r "${PROVISION_DIR}"/* "${BUILD_DIR}/config/includes.binary/provisioning/" 2>/dev/null || true + log "Copied provisioning files" + fi } -build_packages() { - header "Building Debian Packages" - - cd "${PROJECT_ROOT}" - - # Build each package - for pkg in cortex-archive-keyring cortex-core cortex-full; do +build_iso() { + header "Building ISO" + + cd "$BUILD_DIR" + + log "Starting live-build (this may take a while)..." + sudo lb build + + log "Build complete" +} + +move_output() { + local iso_file="${BUILD_DIR}/live-image-${ARCH}.hybrid.iso" + local output_name="${ISO_NAME}-${ISO_VERSION}-${ARCH}.iso" + + header "Moving output" + + mkdir -p "$OUTPUT_DIR" + + if [ -f "$iso_file" ]; then + mv "$iso_file" "${OUTPUT_DIR}/${output_name}" + log "ISO built: ${OUTPUT_DIR}/${output_name}" + + # Generate checksums + cd "$OUTPUT_DIR" + sha256sum "$output_name" > "${output_name}.sha256" + log "Checksum generated: ${output_name}.sha256" + else + error "ISO file not found at ${iso_file}" + exit 1 + fi +} + +generate_sbom() { + header "Generating SBOM" + + if [ -f "${PROJECT_ROOT}/sbom/generate-sbom.sh" ]; then + chmod +x "${PROJECT_ROOT}/sbom/generate-sbom.sh" + "${PROJECT_ROOT}/sbom/generate-sbom.sh" "${OUTPUT_DIR}/sbom" + log "SBOM generated: ${OUTPUT_DIR}/sbom/" + else + warn "SBOM generator not found at sbom/generate-sbom.sh" + fi +} + +build_local_packages() { + header "Building local packages for ISO" + + # Ensure output directory exists + mkdir -p "$OUTPUT_DIR" + + # Build packages needed for ISO (cortex-branding is required) + # Add more packages here as needed + local iso_packages="cortex-branding" + + for pkg in $iso_packages; do log "Building ${pkg}..." - cd "${PROJECT_ROOT}/packages/${pkg}" - - # Clean previous builds - rm -f ../cortex-*.deb ../cortex-*.buildinfo ../cortex-*.changes 2>/dev/null || true - - # Build - dpkg-buildpackage -us -uc -b - - log "${pkg} built successfully" + build_single_package "$pkg" || warn "Failed to build ${pkg}" done - - # Move packages to output - mkdir -p "${PROJECT_ROOT}/output/packages" - mv "${PROJECT_ROOT}/packages"/*.deb "${PROJECT_ROOT}/output/packages/" 2>/dev/null || true - - log "All packages built: ${PROJECT_ROOT}/output/packages/" + + # Copy built packages to packages.chroot for ISO inclusion + local pkg_dest="${BUILD_DIR}/config/packages.chroot" + mkdir -p "$pkg_dest" + + if ls "${OUTPUT_DIR}"/*.deb 1>/dev/null 2>&1; then + cp "${OUTPUT_DIR}"/*.deb "$pkg_dest/" + log "Copied packages to packages.chroot:" + ls -la "$pkg_dest"/*.deb 2>/dev/null || true + else + warn "No .deb packages found in ${OUTPUT_DIR}" + fi } -configure_live_build() { - header "Configuring Live-Build" - - cd "${PROJECT_ROOT}/iso/live-build" - - # Make auto scripts executable - chmod +x auto/* 2>/dev/null || true - - # Clean previous configuration - sudo lb clean --purge 2>/dev/null || true - - # Run configuration - sudo lb config - - # Copy built packages to chroot - if [ -d "${PROJECT_ROOT}/output/packages" ]; then - mkdir -p config/packages.chroot/ - cp "${PROJECT_ROOT}/output/packages"/*.deb config/packages.chroot/ - log "Packages copied to chroot" +cmd_build() { + header "Building Cortex Linux ISO" + log "Architecture: ${ARCH}" + log "Debian version: ${DEBIAN_VERSION}" + + prepare_build_dir + build_local_packages + copy_grub_theme + configure_live_build + copy_preseed_files + build_iso + move_output + generate_sbom + + header "Build Complete" + log "Output: ${OUTPUT_DIR}/" +} + +# ============================================================================= +# Clean Functions +# ============================================================================= + +cmd_clean() { + header "Cleaning build" + + if [ -d "$BUILD_DIR" ]; then + cd "$BUILD_DIR" + sudo lb clean + log "Clean complete" + else + warn "Build directory not found: ${BUILD_DIR}" fi - - log "Live-build configured" } -build_iso() { - local iso_type="$1" +cmd_clean_all() { + header "Cleaning all build artifacts" + + rm -rf "$BUILD_DIR" + rm -rf "$OUTPUT_DIR" + + log "Full clean complete" +} + +cmd_clean_hooks() { + header "Cleaning hook markers" + + if [ -d "${BUILD_DIR}/.build" ]; then + rm -f "${BUILD_DIR}/.build/chroot_hooks" + rm -f "${BUILD_DIR}/.build/binary_hooks" + log "Cleaned hook markers" + fi + + log "Hooks will re-run on next build" +} + +# ============================================================================= +# Sync Functions +# ============================================================================= + +cmd_sync() { + header "Syncing config" + + if [ -d "$BUILD_DIR" ]; then + [ -d "${ISO_DIR}/live-build/config/hooks" ] && \ + cp -r "${ISO_DIR}/live-build/config/hooks" "${BUILD_DIR}/config/" + # Use -rL to follow symlinks and copy actual content + if [ -d "${ISO_DIR}/live-build/config/includes.chroot" ]; then + rm -rf "${BUILD_DIR}/config/includes.chroot" + cp -rL "${ISO_DIR}/live-build/config/includes.chroot" "${BUILD_DIR}/config/" + fi + [ -d "${ISO_DIR}/live-build/config/includes.binary" ] && \ + cp -r "${ISO_DIR}/live-build/config/includes.binary" "${BUILD_DIR}/config/" + log "Config synced (symlinks dereferenced)" + else + warn "Build directory not found: ${BUILD_DIR}" + fi +} + +# ============================================================================= +# Package Building Functions +# ============================================================================= + +# List of available packages (add new packages here) +AVAILABLE_PACKAGES="cortex-branding" + +# Get package version from DEBIAN/control or debian/changelog +get_package_version() { + local pkg_name="$1" + local pkg_path="${PACKAGES_DIR}/${pkg_name}" + + # Try DEBIAN/control first (binary package format) + if [ -f "${pkg_path}/DEBIAN/control" ]; then + grep -E "^Version:" "${pkg_path}/DEBIAN/control" | awk '{print $2}' | head -1 + return + fi - header "Building ISO: ${iso_type}" + # Try debian/changelog (source package format) + if [ -f "${pkg_path}/debian/changelog" ]; then + head -1 "${pkg_path}/debian/changelog" | grep -oP '\(.*?\)' | tr -d '()' + return + fi - cd "${PROJECT_ROOT}/iso/live-build" + # Default version + echo "1.0.0" +} + +# Get package architecture from DEBIAN/control +get_package_arch() { + local pkg_name="$1" + local pkg_path="${PACKAGES_DIR}/${pkg_name}" + + if [ -f "${pkg_path}/DEBIAN/control" ]; then + grep -E "^Architecture:" "${pkg_path}/DEBIAN/control" | awk '{print $2}' | head -1 + return + fi - # Build - log "Starting build (this may take 30-60 minutes)..." - sudo lb build 2>&1 | tee "${PROJECT_ROOT}/build-${iso_type}.log" + if [ -f "${pkg_path}/debian/control" ]; then + grep -E "^Architecture:" "${pkg_path}/debian/control" | awk '{print $2}' | head -1 + return + fi - # Move output - mkdir -p "${PROJECT_ROOT}/output" + echo "all" +} + +# Build cortex-branding package using dpkg-buildpackage +# The package is self-contained with all assets in packages/cortex-branding/ +build_pkg_cortex_branding() { + local pkg_name="cortex-branding" + local pkg_path="${PACKAGES_DIR}/${pkg_name}" + + log "Building ${pkg_name} (self-contained package)..." + + if [ ! -d "${pkg_path}/debian" ]; then + error "${pkg_name} has no debian/ directory" + return 1 + fi + + # Build using dpkg-buildpackage + cd "$pkg_path" - local iso_file - iso_file=$(find . -maxdepth 1 -name "*.iso" -type f | head -1) + # Clean any previous build artifacts + rm -f ../${pkg_name}_*.deb ../${pkg_name}_*.changes ../${pkg_name}_*.buildinfo 2>/dev/null || true - if [ -n "$iso_file" ] && [ -f "$iso_file" ]; then - local output_name="cortex-linux-${VERSION}-${ARCH}-${iso_type}.iso" - mv "$iso_file" "${PROJECT_ROOT}/output/${output_name}" - - # Generate checksums - cd "${PROJECT_ROOT}/output" - sha256sum "${output_name}" > "${output_name}.sha256" - sha512sum "${output_name}" > "${output_name}.sha512" + if dpkg-buildpackage -us -uc -b; then + # Move built packages to output + mv ../${pkg_name}_*.deb "${OUTPUT_DIR}/" 2>/dev/null || true + mv ../${pkg_name}_*.changes "${OUTPUT_DIR}/" 2>/dev/null || true + mv ../${pkg_name}_*.buildinfo "${OUTPUT_DIR}/" 2>/dev/null || true - log "ISO built: ${PROJECT_ROOT}/output/${output_name}" - log "Checksums generated" + cd "$PROJECT_ROOT" + log "Built: ${pkg_name} -> ${OUTPUT_DIR}/" else - error "ISO build failed - no ISO file found" - error "Check build log: ${PROJECT_ROOT}/build-${iso_type}.log" - exit 1 + cd "$PROJECT_ROOT" + error "dpkg-buildpackage failed for ${pkg_name}" + return 1 fi } -clean_build() { - header "Cleaning Build Environment" - - cd "${PROJECT_ROOT}/iso/live-build" - sudo lb clean --purge 2>/dev/null || true - - rm -rf "${PROJECT_ROOT}/output" 2>/dev/null || true - rm -f "${PROJECT_ROOT}"/*.log 2>/dev/null || true - - log "Build environment cleaned" +# Build a meta-package using dpkg-buildpackage (for packages with debian/ dir) +# Falls back to generic DEBIAN/ build if no debian/ dir +build_meta_package() { + local pkg_name="$1" + local pkg_path="${PACKAGES_DIR}/${pkg_name}" + + log "Building ${pkg_name}..." + + # Try debian/ source format first + if [ -d "${pkg_path}/debian" ]; then + cd "$pkg_path" + if dpkg-buildpackage -us -uc -b 2>/dev/null; then + mv ../"${pkg_name}"_*.deb "${OUTPUT_DIR}/" 2>/dev/null || true + mv ../"${pkg_name}"_*.changes "${OUTPUT_DIR}/" 2>/dev/null || true + mv ../"${pkg_name}"_*.buildinfo "${OUTPUT_DIR}/" 2>/dev/null || true + cd "$PROJECT_ROOT" + log "Built: ${pkg_name}" + return 0 + fi + cd "$PROJECT_ROOT" + fi + + # Fall back to DEBIAN/ binary format + if [ -d "${pkg_path}/DEBIAN" ]; then + build_generic_package "$pkg_name" + return $? + fi + + warn "${pkg_name} has no debian/ or DEBIAN/ directory, skipping" + return 0 } -generate_sbom() { - header "Generating SBOM" - - chmod +x "${PROJECT_ROOT}/sbom/generate-sbom.sh" - "${PROJECT_ROOT}/sbom/generate-sbom.sh" "${PROJECT_ROOT}/output/sbom" +# Build cortex-core package (meta-package) +build_pkg_cortex_core() { + build_meta_package "cortex-core" } -run_tests() { - header "Running Verification Tests" +# Build cortex-full package (meta-package) +build_pkg_cortex_full() { + build_meta_package "cortex-full" +} + +# Build cortex-secops package (meta-package) +build_pkg_cortex_secops() { + build_meta_package "cortex-secops" +} + +# Build a single package by name +build_single_package() { + local pkg_name="$1" + + # Check if package exists + if [ ! -d "${PACKAGES_DIR}/${pkg_name}" ]; then + error "Package not found: ${pkg_name}" + error "Available packages: ${AVAILABLE_PACKAGES}" + return 1 + fi + + # Call the appropriate build function + local build_func="build_pkg_${pkg_name//-/_}" + if declare -f "$build_func" > /dev/null; then + "$build_func" + else + # Generic build for packages with DEBIAN/ directory + build_generic_package "$pkg_name" + fi +} + +# Generic package builder for simple packages +build_generic_package() { + local pkg_name="$1" + local pkg_version + pkg_version=$(get_package_version "$pkg_name") + local pkg_arch + pkg_arch=$(get_package_arch "$pkg_name") + local pkg_dir="${BUILD_DIR}/${pkg_name}" + local pkg_path="${PACKAGES_DIR}/${pkg_name}" + + log "Building ${pkg_name} v${pkg_version} (generic)..." + + # Check for DEBIAN directory + if [ ! -d "${pkg_path}/DEBIAN" ]; then + warn "${pkg_name} has no DEBIAN/ directory, skipping" + return 0 + fi + + # Create package directory + mkdir -p "${pkg_dir}" - chmod +x "${PROJECT_ROOT}/tests"/*.sh + # Copy everything except debian/ and DEBIAN/ + find "${pkg_path}" -mindepth 1 -maxdepth 1 ! -name "debian" ! -name "DEBIAN" -exec cp -r {} "${pkg_dir}/" \; - "${PROJECT_ROOT}/tests/verify-packages.sh" || warn "Package tests had issues" - "${PROJECT_ROOT}/tests/verify-preseed.sh" || warn "Preseed tests had issues" + # Copy DEBIAN control files + mkdir -p "${pkg_dir}/DEBIAN" + cp "${pkg_path}/DEBIAN/"* "${pkg_dir}/DEBIAN/" - # ISO tests if ISO exists - local iso_file - iso_file=$(find "${PROJECT_ROOT}/output" -name "*.iso" -type f | head -1) - if [ -n "$iso_file" ]; then - "${PROJECT_ROOT}/tests/verify-iso.sh" "$iso_file" || warn "ISO tests had issues" + # Make maintainer scripts executable + for script in postinst prerm postrm preinst; do + [ -f "${pkg_dir}/DEBIAN/${script}" ] && chmod 755 "${pkg_dir}/DEBIAN/${script}" + done + + # Build the package + local output_file="${OUTPUT_DIR}/${pkg_name}_${pkg_version}_${pkg_arch}.deb" + dpkg-deb --build "$pkg_dir" "$output_file" + rm -rf "$pkg_dir" + + log "Built: ${output_file}" +} + +# Main package build command +cmd_build_package() { + local target="${1:-all}" + + header "Building Packages" + mkdir -p "$OUTPUT_DIR" + + if [ "$target" = "all" ]; then + log "Building all packages..." + for pkg in $AVAILABLE_PACKAGES; do + if [ -d "${PACKAGES_DIR}/${pkg}" ]; then + build_single_package "$pkg" || warn "Failed to build ${pkg}" + fi + done + else + build_single_package "$target" fi + + echo "" + log "Packages in ${OUTPUT_DIR}:" + ls -la "${OUTPUT_DIR}"/*.deb 2>/dev/null || echo " (none)" +} + + +# ============================================================================= +# Help +# ============================================================================= + +cmd_help() { + cat << EOF +Cortex Linux Build Script + +Usage: $0 [args] + +Build Commands: + build Build Cortex Linux ISO + build-package [name] Build .deb packages (default: all) + Available: ${AVAILABLE_PACKAGES} + +Validation Commands: + check-deps Check build dependencies + validate [mode] Run validation (all|preseed|provision|hooks|lint) + test Run test suite + +Clean Commands: + clean Clean build artifacts + clean-all Clean all build artifacts and output + clean-hooks Clean hook markers for re-run + +Utility Commands: + sync Sync config files to build directory + help Show this help + +Environment Variables: + ARCH Architecture (default: amd64) + DEBIAN_VERSION Debian version (default: bookworm) + ISO_NAME ISO name prefix (default: cortex-linux) + ISO_VERSION ISO version (default: YYYYMMDD) + +Examples: + $0 build # Build ISO + ARCH=arm64 $0 build # Build ARM64 ISO + $0 build-package # Build all packages + $0 build-package cortex-branding # Build only cortex-branding + $0 validate + $0 test + $0 clean-all +EOF } -# Parse arguments -CLEAN=false -while [[ $# -gt 0 ]]; do - case "$1" in - -v|--version) - VERSION="$2" - shift 2 +# ============================================================================= +# Entry Point +# ============================================================================= + +main() { + local cmd="${1:-help}" + shift || true + + case "$cmd" in + build) + cmd_build "$@" + ;; + check-deps) + cmd_check_deps + ;; + validate) + cmd_validate "$@" + ;; + test) + cmd_test ;; - -a|--arch) - ARCH="$2" - shift 2 + clean) + cmd_clean "$@" ;; - -c|--clean) - CLEAN=true - shift + clean-all) + cmd_clean_all ;; - -h|--help) - usage - exit 0 + clean-hooks) + cmd_clean_hooks ;; - netinst|offline|packages|all) - BUILD_TYPE="$1" - shift + sync) + cmd_sync "$@" + ;; + build-package|package|branding-package) + cmd_build_package "$@" + ;; + help|--help|-h) + cmd_help ;; *) - error "Unknown option: $1" - usage + error "Unknown command: $cmd" + cmd_help exit 1 ;; esac -done - -# Main execution -header "Cortex Linux Build System" -log "Version: ${VERSION}" -log "Architecture: ${ARCH}" -log "Build Type: ${BUILD_TYPE}" - -# Clean if requested -if [ "$CLEAN" = true ]; then - clean_build -fi - -# Check requirements -check_requirements - -# Build based on type -case "$BUILD_TYPE" in - packages) - build_packages - ;; - netinst) - build_packages - configure_live_build - build_iso "netinst" - generate_sbom - run_tests - ;; - offline) - build_packages - configure_live_build - build_iso "offline" - generate_sbom - run_tests - ;; - all) - build_packages - configure_live_build - build_iso "netinst" - clean_build - configure_live_build - build_iso "offline" - generate_sbom - run_tests - ;; - *) - error "Unknown build type: ${BUILD_TYPE}" - usage - exit 1 - ;; -esac +} -header "Build Complete" -log "Output: ${PROJECT_ROOT}/output/" -ls -la "${PROJECT_ROOT}/output/" 2>/dev/null || true +main "$@" diff --git a/scripts/install-deps.sh b/scripts/install-deps.sh new file mode 100755 index 0000000..d8122fa --- /dev/null +++ b/scripts/install-deps.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# Cortex Linux Build Dependencies Installer +# Copyright 2025 AI Venture Holdings LLC +# SPDX-License-Identifier: Apache-2.0 + +set -e + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +log() { echo -e "${GREEN}[+]${NC} $1"; } +warn() { echo -e "${YELLOW}[!]${NC} $1"; } +error() { echo -e "${RED}[ERROR]${NC} $1" >&2; } + +# Check if running as root +if [ "$(id -u)" -ne 0 ]; then + error "This script must be run as root (use sudo)" + exit 1 +fi + +ARCH=$(dpkg --print-architecture) + +log "Installing Cortex Linux build dependencies for ${ARCH}..." + +# Update package lists +apt-get update + +# Common packages for all architectures +COMMON_PACKAGES=( + git + make + sudo + live-build + debootstrap + squashfs-tools + xorriso + isolinux + syslinux-efi + mtools + dosfstools + imagemagick + gnupg + python3 + shellcheck + dpkg-dev + liblz4-tool +) + +log "Installing common packages..." +apt-get install -y "${COMMON_PACKAGES[@]}" + +# Architecture-specific bootloader packages +if [ "$ARCH" = "amd64" ]; then + log "Installing amd64-specific bootloader packages..." + apt-get install -y grub-pc-bin grub-efi-amd64-bin +elif [ "$ARCH" = "arm64" ]; then + log "Installing arm64-specific bootloader packages..." + apt-get install -y grub-efi-arm64-bin +else + warn "Unknown architecture: ${ARCH}" + warn "You may need to install bootloader packages manually" +fi + +log "All dependencies installed successfully!"