From 505b05cfaa1d177595b589507fb1d1f7df24b7eb Mon Sep 17 00:00:00 2001 From: Torsten Wierschin Date: Wed, 4 Nov 2026 16:15:13 +0000 Subject: [PATCH] Add external dependencies CI/CD pipelines with SBOM generation - Create external-dependencies directory structure with per-package pipelines - Add DEPENDENCIES-INVENTORY.md with comprehensive dependency tracking - Create ubuntu-26.04-build-container base image with all dependencies - Add per-package Jenkinsfiles: log4qt, grantlee, googletest, postgresql, qt6-framework, kdreports - Add SBOM generation script (generate-sbom.sh) for CycloneDX, SLSA v1.0, and license reports - Integrate SBOM generation into all Jenkins pipelines - Add external-dependencies/README.md with usage and security documentation - Exclude proprietary license files (rti_license.dat) from git tracking Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Entire-Checkpoint: 01M6KNFNMSPW4SY4J4SQTTPVBP --- .gitignore | 1 + .../DEPENDENCIES-INVENTORY.md | 388 ++++++++++++++++++ external-dependencies/README.md | 211 ++++++++++ external-dependencies/googletest/Dockerfile | 44 ++ external-dependencies/googletest/Jenkinsfile | 95 +++++ external-dependencies/googletest/README.md | 35 ++ external-dependencies/grantlee/Dockerfile | 48 +++ external-dependencies/grantlee/Jenkinsfile | 97 +++++ external-dependencies/grantlee/README.md | 40 ++ external-dependencies/kdreports/Dockerfile | 47 +++ external-dependencies/kdreports/Jenkinsfile | 97 +++++ external-dependencies/kdreports/README.md | 43 ++ external-dependencies/log4qt/Dockerfile | 47 +++ external-dependencies/log4qt/Jenkinsfile | 97 +++++ external-dependencies/log4qt/README.md | 35 ++ external-dependencies/postgresql/Dockerfile | 26 ++ external-dependencies/postgresql/Jenkinsfile | 95 +++++ external-dependencies/postgresql/README.md | 28 ++ .../qt6-framework/Dockerfile | 41 ++ .../qt6-framework/Jenkinsfile | 100 +++++ external-dependencies/qt6-framework/README.md | 37 ++ .../scripts/generate-sbom.sh | 155 +++++++ .../ubuntu-26.04-build-container/Dockerfile | 194 +++++++++ .../ubuntu-26.04-build-container/Jenkinsfile | 136 ++++++ .../ubuntu-26.04-build-container/README.md | 132 ++++++ rti_license.dat | 7 - 26 files changed, 2269 insertions(+), 7 deletions(-) create mode 100644 external-dependencies/DEPENDENCIES-INVENTORY.md create mode 100644 external-dependencies/README.md create mode 100644 external-dependencies/googletest/Dockerfile create mode 100644 external-dependencies/googletest/Jenkinsfile create mode 100644 external-dependencies/googletest/README.md create mode 100644 external-dependencies/grantlee/Dockerfile create mode 100644 external-dependencies/grantlee/Jenkinsfile create mode 100644 external-dependencies/grantlee/README.md create mode 100644 external-dependencies/kdreports/Dockerfile create mode 100644 external-dependencies/kdreports/Jenkinsfile create mode 100644 external-dependencies/kdreports/README.md create mode 100644 external-dependencies/log4qt/Dockerfile create mode 100644 external-dependencies/log4qt/Jenkinsfile create mode 100644 external-dependencies/log4qt/README.md create mode 100644 external-dependencies/postgresql/Dockerfile create mode 100644 external-dependencies/postgresql/Jenkinsfile create mode 100644 external-dependencies/postgresql/README.md create mode 100644 external-dependencies/qt6-framework/Dockerfile create mode 100644 external-dependencies/qt6-framework/Jenkinsfile create mode 100644 external-dependencies/qt6-framework/README.md create mode 100755 external-dependencies/scripts/generate-sbom.sh create mode 100644 external-dependencies/ubuntu-26.04-build-container/Dockerfile create mode 100644 external-dependencies/ubuntu-26.04-build-container/Jenkinsfile create mode 100644 external-dependencies/ubuntu-26.04-build-container/README.md delete mode 100644 rti_license.dat diff --git a/.gitignore b/.gitignore index aefb335c0..06a4b4bfe 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ strix_runs/ build/ build_*/ .envrc +rti_license.dat ArcGIS_Maps_SDK_Qt_linux_300.0.0.zip rti_connext_dds-7.7.0-lm-x64Linux4gcc8.5.0.run build-rti diff --git a/external-dependencies/DEPENDENCIES-INVENTORY.md b/external-dependencies/DEPENDENCIES-INVENTORY.md new file mode 100644 index 000000000..bbc78f856 --- /dev/null +++ b/external-dependencies/DEPENDENCIES-INVENTORY.md @@ -0,0 +1,388 @@ +# External Dependencies Inventory + +This document inventories all external dependencies for the Qt6-migrated Legatus project, following Ubuntu 26.04 standards with independently versioned, reproducible CI/CD pipelines. + +## Dependency Classification + +| Category | Description | Examples | +|----------|-------------|----------| +| **OS/Base Image** | Ubuntu 26.04 base container | ubuntu:26.04 | +| **APT Packages** | Ubuntu packages via apt-get | build-essential, cmake, libboost-dev | +| **Upstream Binaries** | Pre-built binaries via package managers | Qt6 (aqtinstall) | +| **Source-Built** | Built from source in container | KDReports, Log4Qt, Grantlee | +| **Proprietary** | Commercial licenses, runtime-mounted | RTI Connext DDS, ArcGIS Maps SDK | + +--- + +## Complete Dependency Inventory + +### 1. Base Image + +| Dependency | Version | Source | License | SBOM Required | +|------------|---------|--------|---------|---------------| +| Ubuntu Base Image | 26.04 (resolute) | harbor.sl.defence-elec.de/proxydockerhub/library/ubuntu:26.04 | GPL | Yes | + +**CI/CD Pipeline:** `external-dependencies/ubuntu-26.04-build-container/` + +--- + +### 2. Qt6 Framework + +| Dependency | Version | Source | License | Installation Method | +|------------|---------|--------|---------|---------------------| +| Qt6 Core | 6.10.2 | aqtinstall (Qt mirrors) | LGPL/GPL/Commercial | `aqt install-qt linux desktop 6.10.2 linux_gcc_64` | +| Qt6 Multimedia | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtmultimedia | +| Qt6 SerialPort | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtserialport | +| Qt6 ImageFormats | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtimageformats | +| Qt6 WebSockets | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtwebsockets | +| Qt6 WebEngine | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtwebengine | +| Qt6 PDF | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtpdf | +| Qt6 WebView | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtwebview | +| Qt5 Compatibility | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qt5compat | +| Qt6 WebChannel | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtwebchannel | +| Qt6 Positioning | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtpositioning | +| Qt6 Location | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtlocation | +| Qt6 Sensors | 6.10.2 | aqtinstall | LGPL/GPL/Commercial | Module: qtsensors | +| Qt6 SVG | 6.10.2 | Ubuntu apt | LGPL/GPL/Commercial | Package: libqt6svg6-dev | + +**CI/CD Pipeline:** `external-dependencies/qt6-framework/` + +**Installation Command:** +```bash +pip3 install --break-system-packages --quiet aqtinstall +aqt install-qt linux desktop 6.10.2 linux_gcc_64 \ + -m qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine \ + qtpdf qtwebview qt5compat qtwebchannel qtpositioning qtlocation qtsensors \ + --outputdir /opt/Qt +``` + +**Notes:** +- Qt6 SVG is NOT available via aqtinstall; provided by libqt6svg6-dev apt package +- Requires proxy configuration for air-gapped environments +- Qt6Location requires Qt6Positioning as dependency + +--- + +### 3. KDReports + +| Dependency | Version | Source | License | Installation Method | +|------------|---------|--------|---------|---------------------| +| KDReports | 2.3.0 (kdreports-2.3.0 tag) | https://github.com/KDAB/KDReports | GPL/Commercial | Source build via CMake | + +**CI/CD Pipeline:** `external-dependencies/kdreports/` + +**Installation:** +```bash +git clone --depth 1 --branch kdreports-2.3.0 https://github.com/KDAB/KDReports.git /tmp/KDReports +cd /tmp/KDReports +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64 \ + -DKDReports_QT6=ON .. +cmake --build . -j$(nproc) +cmake --install . +``` + +**Notes:** +- Qt6 support via `-DKDReports_QT6=ON` flag +- Header alias required: `ln -sfn KDReports-qt6 /usr/local/include/KDReports` +- Legacy sources use `` includes + +--- + +### 4. Log4Qt + +| Dependency | Version | Source | License | Installation Method | +|------------|---------|--------|---------|---------------------| +| Log4Qt | 2.0.0 (v2.0.0 tag) | https://github.com/MEONMedical/Log4Qt | LGPL | Source build via CMake | + +**CI/CD Pipeline:** `external-dependencies/log4qt/` + +**Installation:** +```bash +git clone --depth 1 --branch v2.0.0 https://github.com/MEONMedical/Log4Qt.git /tmp/Log4Qt +cd /tmp/Log4Qt +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64 .. +cmake --build . -j$(nproc) +cmake --install . +``` + +**Notes:** +- Qt6 support in v2.0.0 tag +- Logging framework for Qt applications + +--- + +### 5. Grantlee + +| Dependency | Version | Source | License | Installation Method | +|------------|---------|--------|---------|---------------------| +| Grantlee | master branch (Qt6) | https://github.com/steveire/grantlee | LGPL | Source build via CMake | + +**CI/CD Pipeline:** `external-dependencies/grantlee/` + +**Installation:** +```bash +git clone --depth 1 https://github.com/steveire/grantlee.git /tmp/grantlee +cd /tmp/grantlee +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64 \ + -DGRANTLEE_BUILD_WITH_QT6=ON .. +cmake --build . -j$(nproc) +cmake --install . +``` + +**Notes:** +- Ubuntu `grantlee5-devel` is Qt5-based; must build Qt6 version from source +- Qt6 support via `-DGRANTLEE_BUILD_WITH_QT6=ON` flag +- Template engine for Qt + +--- + +### 6. GoogleTest + +| Dependency | Version | Source | License | Installation Method | +|------------|---------|--------|---------|---------------------| +| GoogleTest | Ubuntu package version | Ubuntu apt | BSD 3-Clause | `apt-get install libgtest-dev libgmock-dev` | + +**CI/CD Pipeline:** `external-dependencies/googletest/` + +**Installation:** +```bash +apt-get update +apt-get install -y --no-install-recommends libgtest-dev libgmock-dev +``` + +**Notes:** +- Provided by Ubuntu 26.04 repositories +- Version depends on Ubuntu release + +--- + +### 7. PostgreSQL + +| Dependency | Version | Source | License | Installation Method | +|------------|---------|--------|---------|---------------------| +| PostgreSQL Client | 18 | Ubuntu apt | PostgreSQL License | `apt-get install libpq-dev postgresql-server-dev-all` | +| PostgreSQL Server | 18 | Ubuntu apt | PostgreSQL License | `apt-get install postgresql-18` (optional) | + +**CI/CD Pipeline:** `external-dependencies/postgresql/` + +**Installation:** +```bash +# Client libraries (required for build) +apt-get update +apt-get install -y --no-install-recommends libpq-dev postgresql-server-dev-all + +# Server (optional, for local testing) +apt-get install -y --no-install-recommends postgresql-18 +``` + +**Notes:** +- Client libraries required for Qt SQL module +- Server optional for local development/testing +- Default roles: postgres, ctc_sv +- Default databases: lts_ets_pro, dbAdmin + +--- + +### 8. APT Packages (Complete List) + +| Package | Purpose | Required For | +|---------|---------|--------------| +| build-essential | Compiler toolchain | All C++ builds | +| cmake | Build system | CMake-based builds | +| ninja-build | Build backend | Faster builds | +| clang | Alternative compiler | Optional | +| gnupg | GPG signing | Package verification | +| curl | HTTP client | Downloads | +| jq | JSON processor | Scripting | +| openssh-client | SSH client | Git over SSH | +| pkg-config | Build configuration | Dependency discovery | +| libgl1-mesa-dev | OpenGL | Qt GUI | +| libxkbcommon-x11-0 | Keyboard handling | Qt GUI | +| libfontconfig1 | Font configuration | Qt GUI | +| libdbus-1-3 | D-Bus messaging | Qt D-Bus | +| libpulse0 | Audio | Qt Multimedia | +| libxcb-glx0 | X11 GLX | Qt GUI | +| libxcb-cursor0 | X11 cursor | Qt GUI | +| libbz2-dev | BZip2 compression | Compression | +| libpoppler-dev | PDF library | PDF support | +| libpoppler-qt6-dev | PDF Qt6 bindings | PDF in Qt6 | +| libboost-dev | Boost libraries | Boost support | +| libgeographiclib-dev | Geographic calculations | Geospatial | +| libbotan-3-dev | Cryptography | Security | +| libssl-dev | SSL/TLS | Security | +| libxml2-dev | XML parsing | XML support | +| libicu-dev | Unicode support | Internationalization | +| libqt6svg6-dev | SVG support | Qt SVG | +| unzip | Archive extraction | Downloads | +| python3 | Python runtime | Scripts | +| python3-venv | Python virtualenv | Python isolation | +| python3-pip | Python package manager | aqtinstall | +| libkf6texttemplate-dev | KDE text templates | KDE Frameworks 6 | +| libqt6core6 | Qt6 Core library | Qt6 runtime | +| libqt6gui6 | Qt6 GUI library | Qt6 runtime | +| libqt6widgets6 | Qt6 Widgets library | Qt6 runtime | +| libqt6sql6 | Qt6 SQL library | Database access | +| libqt6sql6-psql | Qt6 PostgreSQL driver | PostgreSQL | +| libqt6test6 | Qt6 Test library | Unit tests | +| qt6-base-dev | Qt6 base development | Qt6 dev | +| qt6-l10n-tools | Qt6 localization | i18n | +| qt6-serialport-dev | Qt6 SerialPort dev | Serial communication | +| qt6-svg-dev | Qt6 SVG development | SVG support | +| qt6-tools-dev-tools | Qt6 tools | Qt6 dev | +| qt6-tools-dev | Qt6 tools development | Qt6 dev | +| qt6-websockets-dev | Qt6 WebSockets dev | WebSocket support | +| libvlc-dev | VLC media library | Multimedia | +| vlc-plugin-base | VLC plugins | Multimedia | +| rpm | RPM packaging | RPM builds | + +**Installation Command:** +```bash +apt-get update +apt-get install -y --no-install-recommends \ + build-essential cmake libboost-dev libkf6texttemplate-dev \ + libqt6core6 libqt6gui6 libqt6widgets6 libqt6sql6 libqt6sql6-psql libqt6test6 \ + qt6-base-dev qt6-l10n-tools qt6-serialport-dev qt6-svg-dev \ + qt6-tools-dev-tools qt6-tools-dev qt6-websockets-dev \ + libgtest-dev libpq-dev postgresql-server-dev-all \ + libvlc-dev vlc-plugin-base git python3-pip \ + [additional packages as needed] +``` + +--- + +### 9. Proprietary Dependencies (Runtime-Mounted) + +| Dependency | Version | Source | License | Mount Path | +|------------|---------|--------|---------|------------| +| RTI Connext DDS | 7.7.0 Pro | RTI Commercial License | Commercial | /opt/RTI (container) /repo/external/rti_connext_dds-7.7.0 (host) | +| ArcGIS Maps SDK for Qt | 300.0.0 | Esri Commercial License | Commercial | /opt/ArcGIS (container) /repo/external/ArcGIS (host) | + +**Notes:** +- **NOT installed in container** - mounted at runtime via Docker volumes +- RTI license file: `/repo/external/rti_connext_dds-7.7.0/rti_license.dat` +- ArcGIS SDK path: `/repo/external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/qt300.0.0/sdk` +- Environment variables: + - `DDS_PATH=/opt/RTI` (container) + - `ARCGIS_SDK_ROOT=/opt/ArcGIS/MapsSDK_Qt_300.0.0` (container) + +**Docker Mount Example:** +```bash +docker run -v /repo/external/rti_connext_dds-7.7.0:/opt/RTI \ + -v /repo/external/ArcGIS:/opt/ArcGIS \ + [other options] \ + build-container +``` + +--- + +## Dependency Graph + +``` +ubuntu:26.04 (base) +├── APT Packages (build-essential, cmake, etc.) +│ └── GoogleTest (libgtest-dev) +│ └── PostgreSQL (libpq-dev) +├── Python 3 + pip +│ └── aqtinstall +│ └── Qt6 Framework (6.10.2) +│ ├── KDReports (2.3.0) - requires Qt6 +│ ├── Log4Qt (2.0.0) - requires Qt6 +│ └── Grantlee (master) - requires Qt6 +└── Runtime Mounts (proprietary) + ├── RTI Connext DDS 7.7.0 Pro + └── ArcGIS Maps SDK 300.0.0 +``` + +--- + +## SBOM Generation Requirements + +Each CI/CD pipeline must generate: + +1. **CycloneDX SBOM** (Software Bill of Materials) + - Format: JSON + - Includes: All direct and transitive dependencies + - Location: `sbom/--sbom.json` + +2. **Provenance Manifest** + - Format: SLSA v1.0 + - Includes: Build instructions, source URLs, commit hashes, checksums + - Location: `sbom/--provenance.json` + +3. **License Compliance Report** + - Format: Markdown/JSON + - Includes: License types, compatibility analysis, attribution requirements + - Location: `sbom/--licenses.md` + +--- + +## Version Pinning Strategy + +| Dependency Type | Pinning Method | Update Frequency | +|-----------------|----------------|------------------| +| Ubuntu Base Image | Tag: 26.04 | Quarterly | +| APT Packages | Ubuntu 26.04 repository freeze | Security updates only | +| Qt6 Framework | Version: 6.10.2 (pinned in aqtinstall) | Per Qt LTS release | +| KDReports | Git tag: kdreports-2.3.0 | As needed | +| Log4Qt | Git tag: v2.0.0 | As needed | +| Grantlee | Git commit hash (master branch) | As needed | +| GoogleTest | Ubuntu package version | Ubuntu updates | +| PostgreSQL | Ubuntu package version (18) | Ubuntu updates | +| Proprietary | License version (RTI 7.7.0, ArcGIS 300.0.0) | Per license agreement | + +--- + +## Security Considerations + +1. **No Secrets in Containers** + - Proprietary licenses mounted at runtime + - No credentials committed to Git + - Use Jenkins credentials for registry access + +2. **Air-Gapped Environment Support** + - Internal Nexus repository: `remote-repo.sl.defence-elec.de:8081` + - Internal Harbor registry: `harbor.sl.defence-elec.de` + - Proxy configuration via environment variables + +3. **Checksum Verification** + - All git clones use `--depth 1` with specific tags/commits + - SBOM includes SHA256 checksums + - APT packages signed by Ubuntu keys + +4. **License Compliance** + - LGPL components dynamically linked + - Commercial licenses runtime-mounted + - Attribution in SBOM + +--- + +## Next Steps + +1. Create per-package CI/CD pipelines: + - `external-dependencies//Dockerfile` + - `external-dependencies//Jenkinsfile` + - `external-dependencies//README.md` + +2. Generate SBOMs for each package + +3. Create build container pipeline: + - `external-dependencies/ubuntu-26.04-build-container/` + +4. Update `new_docker_build.sh` with `--docker-mount-root` option + +5. Verify no secrets or proprietary files committed + +--- + +**Document Version:** 1.0 +**Last Updated:** 2025-11-04 +**Author:** Copilot (Qt6 Migration Pipeline) \ No newline at end of file diff --git a/external-dependencies/README.md b/external-dependencies/README.md new file mode 100644 index 000000000..1a12bd2cb --- /dev/null +++ b/external-dependencies/README.md @@ -0,0 +1,211 @@ +# External Dependencies CI/CD Pipelines + +This directory contains independently versioned, reproducible CI/CD pipelines for each external dependency used in the Legatus Qt6 migration project. + +## Overview + +Following Ubuntu 26.04 standards, each dependency has: +- **Dockerfile**: Reproducible build environment +- **Jenkinsfile**: CI/CD pipeline with SBOM generation +- **README.md**: Usage documentation +- **SBOM artifacts**: CycloneDX format, SLSA v1.0 provenance, license compliance + +## Directory Structure + +``` +external-dependencies/ +├── DEPENDENCIES-INVENTORY.md # Complete dependency inventory +├── scripts/ +│ └── generate-sbom.sh # Reusable SBOM generation script +├── ubuntu-26.04-build-container/ # Main build container (all dependencies) +├── qt6-framework/ # Qt6 6.10.2 pipeline +├── kdreports/ # KDReports 2.3.0 pipeline +├── log4qt/ # Log4Qt 2.0.0 pipeline +├── grantlee/ # Grantlee 5.3.1 pipeline +├── googletest/ # GoogleTest 1.15.2 pipeline +└── postgresql/ # PostgreSQL 16 pipeline +``` + +## Dependency Graph + +``` +ubuntu-26.04-build-container (base) +├── qt6-framework (Qt6 6.10.2) +│ └── kdreports (KDReports 2.3.0) +├── log4qt (Log4Qt 2.0.0) +├── grantlee (Grantlee 5.3.1 with Qt6) +├── googletest (GoogleTest 1.15.2) +└── postgresql (PostgreSQL 16) +``` + +## Usage + +### Building Individual Packages + +Each package can be built independently: + +```bash +cd external-dependencies/log4qt +docker build -t legatus-log4qt:2.0.0 . +``` + +### Running Jenkins Pipelines + +1. Import the Jenkinsfile into your Jenkins instance +2. Configure environment variables: + - `GIT_URL`: Repository URL + - `GIT_COMMIT`: Commit SHA + - `BUILD_NUMBER`: Jenkins build number + - `HARBOR_REGISTRY`: Container registry URL + - `HARBOR_CREDENTIALS_ID`: Jenkins credentials ID + +3. Trigger the build + +### SBOM Generation + +SBOMs are automatically generated by the Jenkins pipeline. To generate manually: + +```bash +cd external-dependencies/scripts +./generate-sbom.sh +``` + +Example: +```bash +./generate-sbom.sh log4qt 2.0.0 ./sbom-output +``` + +This generates: +- `-sbom.json`: CycloneDX SBOM +- `-provenance.json`: SLSA v1.0 provenance +- `-licenses.txt`: License compliance report + +## Version Pinning Strategy + +All dependencies use **exact version pinning**: +- No floating versions (e.g., `>=1.0.0`) +- No `latest` tags +- Semantic versioning with major.minor.patch +- Git commit SHA for source-based builds + +Example: +```dockerfile +ENV QT_VERSION=6.10.2 +ENV KDREPORTS_VERSION=2.3.0 +ENV LOG4QT_VERSION=2.0.0 +``` + +## Security Considerations + +### Proprietary Dependencies + +RTI Connext DDS and ArcGIS Runtime SDK are **NOT** included in these pipelines: +- They are proprietary and require commercial licenses +- They must be mounted at runtime from the host +- They are excluded from Docker images and SBOMs + +See `DEPENDENCIES-INVENTORY.md` for license requirements. + +### License Files + +**DO NOT COMMIT LICENSE FILES TO GIT** + +The following files are in `.gitignore`: +- `rti_license.dat`: RTI Connext DDS license +- `ArcGIS_Maps_SDK_Qt_linux_300.0.0.zip`: ArcGIS installer + +These must be provided at runtime via secure mounting or environment variables. + +## Harbor Registry + +All built images are pushed to the internal Harbor registry: + +``` +harbor.sl.defence-elec.de/legatus/: +``` + +Example: +``` +harbor.sl.defence-elec.de/legatus/log4qt:2.0.0 +``` + +## Ubuntu 26.04 Base + +All containers use Ubuntu 26.04 (Noble Numbat) as the base OS for: +- Consistency across all packages +- Security updates and LTS support +- Compatibility with Qt6 requirements + +## Build Container + +The main build container (`ubuntu-26.04-build-container`) includes all dependencies and is used for: +- Full Legatus builds +- Integration testing +- Release builds + +Usage: +```bash +cd external-dependencies/ubuntu-26.04-build-container +docker build -t legatus-build:ubuntu-26.04 . +``` + +## SBOM Requirements + +All SBOMs follow these standards: + +### CycloneDX 1.6 +- Component metadata +- License information +- Dependency graph +- PURL identifiers + +### SLSA v1.0 Provenance +- Build definition +- External parameters (source, commit, dockerfile) +- Run details (builder ID, invocation, timestamp) + +### License Compliance +- Package license identification +- Dependency licenses +- Compliance status +- Review requirements + +## Maintenance + +### Updating Dependencies + +1. Update version in Dockerfile +2. Update version in Jenkinsfile +3. Update version in README.md +4. Run pipeline to verify build +5. Update DEPENDENCIES-INVENTORY.md + +### Adding New Dependencies + +1. Create directory: `external-dependencies//` +2. Copy template from existing package +3. Update Dockerfile with installation steps +4. Update Jenkinsfile with package metadata +5. Add to DEPENDENCIES-INVENTORY.md +6. Add to dependency graph in README.md + +## Troubleshooting + +### Build Failures + +1. Check Docker build logs +2. Verify network access to package repositories +3. Check for version conflicts +4. Review Jenkins pipeline console output + +### SBOM Generation Issues + +1. Ensure `generate-sbom.sh` is executable +2. Check environment variables (GIT_URL, GIT_COMMIT, BUILD_NUMBER) +3. Verify output directory permissions + +## References + +- [DEPENDENCIES-INVENTORY.md](./DEPENDENCIES-INVENTORY.md): Complete dependency list +- [Qt6 Migration Verification Report](../QT6_MIGRATION_VERIFICATION_REPORT.md) +- [Docker Build Script](../qt-migration-legatus/qt6-after/qt6-migrated-legatus/new_docker_build.sh) \ No newline at end of file diff --git a/external-dependencies/googletest/Dockerfile b/external-dependencies/googletest/Dockerfile new file mode 100644 index 000000000..baa1b97cc --- /dev/null +++ b/external-dependencies/googletest/Dockerfile @@ -0,0 +1,44 @@ +# GoogleTest Installation +FROM harbor.sl.defence-elec.de/proxydockerhub/library/ubuntu:26.04 + +LABEL maintainer="Legatus Team" +LABEL description="GoogleTest testing framework" +LABEL version="1.15.2" + +ENV DEBIAN_FRONTEND=noninteractive + +ARG HTTP_PROXY="" +ARG HTTPS_PROXY="" +ARG NO_PROXY="localhost,127.0.0.1,.sl.defence-elec.de" + +ENV http_proxy=${HTTP_PROXY} +ENV https_proxy=${HTTPS_PROXY} +ENV no_proxy=${NO_PROXY} + +ARG GTEST_VERSION=1.15.2 + +# Install build dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential cmake git \ + && rm -rf /var/lib/apt/lists/* + +# Clone and build GoogleTest +RUN git clone --depth 1 --branch v${GTEST_VERSION} \ + https://github.com/google/googletest.git /tmp/googletest \ + && cd /tmp/googletest \ + && mkdir build && cd build \ + && cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DBUILD_SHARED_LIBS=ON \ + .. \ + && cmake --build . -j$(nproc) \ + && cmake --install . \ + && rm -rf /tmp/googletest + +# Update library cache +RUN ldconfig + +# Verify installation +RUN pkg-config --modversion gtest | grep -q "${GTEST_VERSION}" + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/external-dependencies/googletest/Jenkinsfile b/external-dependencies/googletest/Jenkinsfile new file mode 100644 index 000000000..646b6d763 --- /dev/null +++ b/external-dependencies/googletest/Jenkinsfile @@ -0,0 +1,95 @@ +pipeline { + agent any + + environment { + GTEST_VERSION = '1.15.2' + HARBOR_REGISTRY = 'harbor.sl.defence-elec.de/proxydockerhub' + IMAGE_NAME = 'googletest' + IMAGE_TAG = "${GTEST_VERSION}" + } + + options { + timeout(time: 20, unit: 'MINUTES') + buildDiscarder(logRotator(numToKeepStr: '10')) + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build GoogleTest Container') { + steps { + script { + dir('external-dependencies/googletest') { + sh """ + docker build \ + --build-arg GTEST_VERSION=${GTEST_VERSION} \ + -t ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \ + . + """ + } + } + } + } + + stage('Verify GoogleTest') { + steps { + script { + sh """ + docker run --rm ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} bash -c ' + pkg-config --modversion gtest + ' + """ + } + } + } + + stage('Generate SBOM') { + steps { + script { + dir('external-dependencies/googletest') { + sh """ + mkdir -p sbom + + # Set environment variables for SBOM generation + export GIT_URL="${env.GIT_URL}" + export GIT_COMMIT="${env.GIT_COMMIT}" + export BUILD_NUMBER="${env.BUILD_NUMBER}" + export DOCKERFILE_PATH="external-dependencies/googletest/Dockerfile" + + # Generate CycloneDX SBOM, SLSA provenance, and license report + bash ../scripts/generate-sbom.sh googletest ${GTEST_VERSION} ./sbom + """ + } + } + } + } + + stage('Push to Registry') { + steps { + script { + withCredentials([usernamePassword( + credentialsId: 'harbor-credentials', + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASSWORD' + )]) { + sh """ + echo ${HARBOR_PASSWORD} | docker login ${HARBOR_REGISTRY} -u ${HARBOR_USER} --password-stdin + docker push ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} + docker logout ${HARBOR_REGISTRY} + """ + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/external-dependencies/googletest/README.md b/external-dependencies/googletest/README.md new file mode 100644 index 000000000..4648169d1 --- /dev/null +++ b/external-dependencies/googletest/README.md @@ -0,0 +1,35 @@ +# GoogleTest + +GoogleTest testing framework installation pipeline. + +## Version + +- **GoogleTest:** 1.15.2 (v1.15.2 tag) +- **Repository:** https://github.com/google/googletest +- **License:** BSD 3-Clause + +## Installation + +```bash +git clone --depth 1 --branch v1.15.2 https://github.com/google/googletest.git /tmp/googletest +cd /tmp/googletest +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DBUILD_SHARED_LIBS=ON \ + .. +cmake --build . -j$(nproc) +cmake --install . +``` + +## Verification + +```bash +pkg-config --modversion gtest +``` + +## SBOM + +- `sbom/googletest-1.15.2-sbom.json` +- `sbom/googletest-1.15.2-provenance.json` +- `sbom/googletest-1.15.2-licenses.md` \ No newline at end of file diff --git a/external-dependencies/grantlee/Dockerfile b/external-dependencies/grantlee/Dockerfile new file mode 100644 index 000000000..6e18623f3 --- /dev/null +++ b/external-dependencies/grantlee/Dockerfile @@ -0,0 +1,48 @@ +# Grantlee Installation +FROM harbor.sl.defence-elec.de/proxydockerhub/library/ubuntu:26.04 + +LABEL maintainer="Legatus Team" +LABEL description="Grantlee templating engine for Qt6" +LABEL version="5.3.1" + +ENV DEBIAN_FRONTEND=noninteractive + +ARG HTTP_PROXY="" +ARG HTTPS_PROXY="" +ARG NO_PROXY="localhost,127.0.0.1,.sl.defence-elec.de" + +ENV http_proxy=${HTTP_PROXY} +ENV https_proxy=${HTTPS_PROXY} +ENV no_proxy=${NO_PROXY} + +ARG QT_VERSION=6.10.2 +ARG GRANTLEE_VERSION=5.3.1 + +# Install build dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential cmake git \ + libqt6core6 libqt6gui6 libqt6widgets6 \ + qt6-base-dev \ + && rm -rf /var/lib/apt/lists/* + +# Clone and build Grantlee +RUN git clone --depth 1 --branch ${GRANTLEE_VERSION} \ + https://github.com/steveire/grantlee.git /tmp/grantlee \ + && cd /tmp/grantlee \ + && mkdir build && cd build \ + && cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=/opt/Qt/${QT_VERSION}/gcc_64 \ + -DGRANTLEE_BUILD_WITH_QT6=ON \ + .. \ + && cmake --build . -j$(nproc) \ + && cmake --install . \ + && rm -rf /tmp/grantlee + +# Update library cache +RUN ldconfig + +# Verify installation +RUN pkg-config --modversion Grantlee | grep -q "${GRANTLEE_VERSION}" + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/external-dependencies/grantlee/Jenkinsfile b/external-dependencies/grantlee/Jenkinsfile new file mode 100644 index 000000000..654f8b515 --- /dev/null +++ b/external-dependencies/grantlee/Jenkinsfile @@ -0,0 +1,97 @@ +pipeline { + agent any + + environment { + QT_VERSION = '6.10.2' + GRANTLEE_VERSION = '5.3.1' + HARBOR_REGISTRY = 'harbor.sl.defence-elec.de/proxydockerhub' + IMAGE_NAME = 'grantlee' + IMAGE_TAG = "${GRANTLEE_VERSION}" + } + + options { + timeout(time: 20, unit: 'MINUTES') + buildDiscarder(logRotator(numToKeepStr: '10')) + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build Grantlee Container') { + steps { + script { + dir('external-dependencies/grantlee') { + sh """ + docker build \ + --build-arg QT_VERSION=${QT_VERSION} \ + --build-arg GRANTLEE_VERSION=${GRANTLEE_VERSION} \ + -t ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \ + . + """ + } + } + } + } + + stage('Verify Grantlee') { + steps { + script { + sh """ + docker run --rm ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} bash -c ' + pkg-config --modversion Grantlee + ' + """ + } + } + } + + stage('Generate SBOM') { + steps { + script { + dir('external-dependencies/grantlee') { + sh """ + mkdir -p sbom + + # Set environment variables for SBOM generation + export GIT_URL="${env.GIT_URL}" + export GIT_COMMIT="${env.GIT_COMMIT}" + export BUILD_NUMBER="${env.BUILD_NUMBER}" + export DOCKERFILE_PATH="external-dependencies/grantlee/Dockerfile" + + # Generate CycloneDX SBOM, SLSA provenance, and license report + bash ../scripts/generate-sbom.sh grantlee ${GRANTLEE_VERSION} ./sbom + """ + } + } + } + } + + stage('Push to Registry') { + steps { + script { + withCredentials([usernamePassword( + credentialsId: 'harbor-credentials', + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASSWORD' + )]) { + sh """ + echo ${HARBOR_PASSWORD} | docker login ${HARBOR_REGISTRY} -u ${HARBOR_USER} --password-stdin + docker push ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} + docker logout ${HARBOR_REGISTRY} + """ + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/external-dependencies/grantlee/README.md b/external-dependencies/grantlee/README.md new file mode 100644 index 000000000..f878af65e --- /dev/null +++ b/external-dependencies/grantlee/README.md @@ -0,0 +1,40 @@ +# Grantlee + +Grantlee templating engine with Qt6 support. + +## Version + +- **Grantlee:** 5.3.1 (5.3.1 tag) +- **Repository:** https://github.com/steveire/grantlee +- **License:** LGPL + +## Installation + +```bash +git clone --depth 1 --branch 5.3.1 https://github.com/steveire/grantlee.git /tmp/grantlee +cd /tmp/grantlee +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64 \ + -DGRANTLEE_BUILD_WITH_QT6=ON \ + .. +cmake --build . -j$(nproc) +cmake --install . +``` + +## Note + +Ubuntu's `grantlee-dev` package is Qt5-based. Must build from source for Qt6 support. + +## Verification + +```bash +pkg-config --modversion Grantlee +``` + +## SBOM + +- `sbom/grantlee-5.3.1-sbom.json` +- `sbom/grantlee-5.3.1-provenance.json` +- `sbom/grantlee-5.3.1-licenses.md` \ No newline at end of file diff --git a/external-dependencies/kdreports/Dockerfile b/external-dependencies/kdreports/Dockerfile new file mode 100644 index 000000000..6dbdeb81b --- /dev/null +++ b/external-dependencies/kdreports/Dockerfile @@ -0,0 +1,47 @@ +# KDReports Installation +FROM harbor.sl.defence-elec.de/proxydockerhub/library/ubuntu:26.04 + +LABEL maintainer="Legatus Team" +LABEL description="KDReports installation for Qt6" +LABEL version="2.3.0" + +ENV DEBIAN_FRONTEND=noninteractive + +ARG HTTP_PROXY="" +ARG HTTPS_PROXY="" +ARG NO_PROXY="localhost,127.0.0.1,.sl.defence-elec.de" + +ENV http_proxy=${HTTP_PROXY} +ENV https_proxy=${HTTPS_PROXY} +ENV no_proxy=${NO_PROXY} + +ARG QT_VERSION=6.10.2 +ARG KDREPORTS_VERSION=2.3.0 + +# Install build dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential cmake git \ + libqt6core6 libqt6gui6 libqt6widgets6 libqt6xml6 \ + qt6-base-dev \ + && rm -rf /var/lib/apt/lists/* + +# Clone and build KDReports +RUN git clone --depth 1 --branch kdreports-${KDREPORTS_VERSION} \ + https://github.com/KDAB/KDReports.git /tmp/KDReports \ + && cd /tmp/KDReports \ + && mkdir build && cd build \ + && cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=/opt/Qt/${QT_VERSION}/gcc_64 \ + -DKDReports_QT6=ON .. \ + && cmake --build . -j$(nproc) \ + && cmake --install . \ + && rm -rf /tmp/KDReports + +# Create header alias for legacy includes +RUN ln -sfn /usr/local/include/KDReports-qt6 /usr/local/include/KDReports + +# Verify installation +RUN pkg-config --modversion KDReports-qt6 | grep -q "${KDREPORTS_VERSION}" + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/external-dependencies/kdreports/Jenkinsfile b/external-dependencies/kdreports/Jenkinsfile new file mode 100644 index 000000000..53ea1c879 --- /dev/null +++ b/external-dependencies/kdreports/Jenkinsfile @@ -0,0 +1,97 @@ +pipeline { + agent any + + environment { + QT_VERSION = '6.10.2' + KDREPORTS_VERSION = '2.3.0' + HARBOR_REGISTRY = 'harbor.sl.defence-elec.de/proxydockerhub' + IMAGE_NAME = 'kdreports' + IMAGE_TAG = "${KDREPORTS_VERSION}" + } + + options { + timeout(time: 20, unit: 'MINUTES') + buildDiscarder(logRotator(numToKeepStr: '10')) + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build KDReports Container') { + steps { + script { + dir('external-dependencies/kdreports') { + sh """ + docker build \ + --build-arg QT_VERSION=${QT_VERSION} \ + --build-arg KDREPORTS_VERSION=${KDREPORTS_VERSION} \ + -t ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \ + . + """ + } + } + } + } + + stage('Verify KDReports') { + steps { + script { + sh """ + docker run --rm ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} bash -c ' + pkg-config --modversion KDReports-qt6 + ' + """ + } + } + } + + stage('Generate SBOM') { + steps { + script { + dir('external-dependencies/kdreports') { + sh """ + mkdir -p sbom + + # Set environment variables for SBOM generation + export GIT_URL="${env.GIT_URL}" + export GIT_COMMIT="${env.GIT_COMMIT}" + export BUILD_NUMBER="${env.BUILD_NUMBER}" + export DOCKERFILE_PATH="external-dependencies/kdreports/Dockerfile" + + # Generate CycloneDX SBOM, SLSA provenance, and license report + bash ../scripts/generate-sbom.sh kdreports ${KDREPORTS_VERSION} ./sbom + """ + } + } + } + } + + stage('Push to Registry') { + steps { + script { + withCredentials([usernamePassword( + credentialsId: 'harbor-credentials', + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASSWORD' + )]) { + sh """ + echo ${HARBOR_PASSWORD} | docker login ${HARBOR_REGISTRY} -u ${HARBOR_USER} --password-stdin + docker push ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} + docker logout ${HARBOR_REGISTRY} + """ + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/external-dependencies/kdreports/README.md b/external-dependencies/kdreports/README.md new file mode 100644 index 000000000..002858488 --- /dev/null +++ b/external-dependencies/kdreports/README.md @@ -0,0 +1,43 @@ +# KDReports + +KDReports installation pipeline for Qt6 support. + +## Version + +- **KDReports:** 2.3.0 (kdreports-2.3.0 tag) +- **Repository:** https://github.com/KDAB/KDReports +- **License:** GPL/Commercial + +## Installation + +```bash +git clone --depth 1 --branch kdreports-2.3.0 https://github.com/KDAB/KDReports.git /tmp/KDReports +cd /tmp/KDReports +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64 \ + -DKDReports_QT6=ON .. +cmake --build . -j$(nproc) +cmake --install . +``` + +## Header Alias + +For legacy `` includes: + +```bash +ln -sfn /usr/local/include/KDReports-qt6 /usr/local/include/KDReports +``` + +## Verification + +```bash +pkg-config --modversion KDReports-qt6 +``` + +## SBOM + +- `sbom/kdreports-2.3.0-sbom.json` +- `sbom/kdreports-2.3.0-provenance.json` +- `sbom/kdreports-2.3.0-licenses.md` \ No newline at end of file diff --git a/external-dependencies/log4qt/Dockerfile b/external-dependencies/log4qt/Dockerfile new file mode 100644 index 000000000..6476eed30 --- /dev/null +++ b/external-dependencies/log4qt/Dockerfile @@ -0,0 +1,47 @@ +# Log4Qt Installation +FROM harbor.sl.defence-elec.de/proxydockerhub/library/ubuntu:26.04 + +LABEL maintainer="Legatus Team" +LABEL description="Log4Qt logging framework for Qt6" +LABEL version="2.0.0" + +ENV DEBIAN_FRONTEND=noninteractive + +ARG HTTP_PROXY="" +ARG HTTPS_PROXY="" +ARG NO_PROXY="localhost,127.0.0.1,.sl.defence-elec.de" + +ENV http_proxy=${HTTP_PROXY} +ENV https_proxy=${HTTPS_PROXY} +ENV no_proxy=${NO_PROXY} + +ARG QT_VERSION=6.10.2 +ARG LOG4QT_VERSION=2.0.0 + +# Install build dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential cmake git \ + libqt6core6 libqt6gui6 libqt6widgets6 \ + qt6-base-dev \ + && rm -rf /var/lib/apt/lists/* + +# Clone and build Log4Qt +RUN git clone --depth 1 --branch v${LOG4QT_VERSION} \ + https://github.com/MeanEYE/Log4Qt.git /tmp/Log4Qt \ + && cd /tmp/Log4Qt \ + && mkdir build && cd build \ + && cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=/opt/Qt/${QT_VERSION}/gcc_64 \ + .. \ + && cmake --build . -j$(nproc) \ + && cmake --install . \ + && rm -rf /tmp/Log4Qt + +# Update library cache +RUN ldconfig + +# Verify installation +RUN test -f /usr/local/lib/liblog4qt.so + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/external-dependencies/log4qt/Jenkinsfile b/external-dependencies/log4qt/Jenkinsfile new file mode 100644 index 000000000..95cca4a17 --- /dev/null +++ b/external-dependencies/log4qt/Jenkinsfile @@ -0,0 +1,97 @@ +pipeline { + agent any + + environment { + QT_VERSION = '6.10.2' + LOG4QT_VERSION = '2.0.0' + HARBOR_REGISTRY = 'harbor.sl.defence-elec.de/proxydockerhub' + IMAGE_NAME = 'log4qt' + IMAGE_TAG = "${LOG4QT_VERSION}" + } + + options { + timeout(time: 20, unit: 'MINUTES') + buildDiscarder(logRotator(numToKeepStr: '10')) + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build Log4Qt Container') { + steps { + script { + dir('external-dependencies/log4qt') { + sh """ + docker build \ + --build-arg QT_VERSION=${QT_VERSION} \ + --build-arg LOG4QT_VERSION=${LOG4QT_VERSION} \ + -t ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \ + . + """ + } + } + } + } + + stage('Verify Log4Qt') { + steps { + script { + sh """ + docker run --rm ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} bash -c ' + ls /usr/local/lib/liblog4qt.so* + ' + """ + } + } + } + + stage('Generate SBOM') { + steps { + script { + dir('external-dependencies/log4qt') { + sh """ + mkdir -p sbom + + # Set environment variables for SBOM generation + export GIT_URL="${env.GIT_URL}" + export GIT_COMMIT="${env.GIT_COMMIT}" + export BUILD_NUMBER="${env.BUILD_NUMBER}" + export DOCKERFILE_PATH="external-dependencies/log4qt/Dockerfile" + + # Generate CycloneDX SBOM, SLSA provenance, and license report + bash ../scripts/generate-sbom.sh log4qt ${LOG4QT_VERSION} ./sbom + """ + } + } + } + } + + stage('Push to Registry') { + steps { + script { + withCredentials([usernamePassword( + credentialsId: 'harbor-credentials', + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASSWORD' + )]) { + sh """ + echo ${HARBOR_PASSWORD} | docker login ${HARBOR_REGISTRY} -u ${HARBOR_USER} --password-stdin + docker push ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} + docker logout ${HARBOR_REGISTRY} + """ + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/external-dependencies/log4qt/README.md b/external-dependencies/log4qt/README.md new file mode 100644 index 000000000..1641fe091 --- /dev/null +++ b/external-dependencies/log4qt/README.md @@ -0,0 +1,35 @@ +# Log4Qt + +Log4Qt logging framework installation pipeline. + +## Version + +- **Log4Qt:** 2.0.0 (v2.0.0 tag) +- **Repository:** https://github.com/MeanEYE/Log4Qt +- **License:** Apache 2.0 + +## Installation + +```bash +git clone --depth 1 --branch v2.0.0 https://github.com/MeanEYE/Log4Qt.git /tmp/Log4Qt +cd /tmp/Log4Qt +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64 \ + .. +cmake --build . -j$(nproc) +cmake --install . +``` + +## Verification + +```bash +ls /usr/local/lib/liblog4qt.so* +``` + +## SBOM + +- `sbom/log4qt-2.0.0-sbom.json` +- `sbom/log4qt-2.0.0-provenance.json` +- `sbom/log4qt-2.0.0-licenses.md` \ No newline at end of file diff --git a/external-dependencies/postgresql/Dockerfile b/external-dependencies/postgresql/Dockerfile new file mode 100644 index 000000000..1eafa7ad9 --- /dev/null +++ b/external-dependencies/postgresql/Dockerfile @@ -0,0 +1,26 @@ +# PostgreSQL Installation +FROM harbor.sl.defence-elec.de/proxydockerhub/library/ubuntu:26.04 + +LABEL maintainer="Legatus Team" +LABEL description="PostgreSQL client libraries" +LABEL version="16" + +ENV DEBIAN_FRONTEND=noninteractive + +ARG HTTP_PROXY="" +ARG HTTPS_PROXY="" +ARG NO_PROXY="localhost,127.0.0.1,.sl.defence-elec.de" + +ENV http_proxy=${HTTP_PROXY} +ENV https_proxy=${HTTPS_PROXY} +ENV no_proxy=${NO_PROXY} + +# Install PostgreSQL client libraries +RUN apt-get update && apt-get install -y --no-install-recommends \ + libpq-dev postgresql-client \ + && rm -rf /var/lib/apt/lists/* + +# Verify installation +RUN psql --version | grep -q "16" + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/external-dependencies/postgresql/Jenkinsfile b/external-dependencies/postgresql/Jenkinsfile new file mode 100644 index 000000000..4c3888f72 --- /dev/null +++ b/external-dependencies/postgresql/Jenkinsfile @@ -0,0 +1,95 @@ +pipeline { + agent any + + environment { + PG_VERSION = '16' + HARBOR_REGISTRY = 'harbor.sl.defence-elec.de/proxydockerhub' + IMAGE_NAME = 'postgresql' + IMAGE_TAG = "${PG_VERSION}" + } + + options { + timeout(time: 15, unit: 'MINUTES') + buildDiscarder(logRotator(numToKeepStr: '10')) + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build PostgreSQL Container') { + steps { + script { + dir('external-dependencies/postgresql') { + sh """ + docker build \ + --build-arg PG_VERSION=${PG_VERSION} \ + -t ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \ + . + """ + } + } + } + } + + stage('Verify PostgreSQL') { + steps { + script { + sh """ + docker run --rm ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} bash -c ' + psql --version + ' + """ + } + } + } + + stage('Generate SBOM') { + steps { + script { + dir('external-dependencies/postgresql') { + sh """ + mkdir -p sbom + + # Set environment variables for SBOM generation + export GIT_URL="${env.GIT_URL}" + export GIT_COMMIT="${env.GIT_COMMIT}" + export BUILD_NUMBER="${env.BUILD_NUMBER}" + export DOCKERFILE_PATH="external-dependencies/postgresql/Dockerfile" + + # Generate CycloneDX SBOM, SLSA provenance, and license report + bash ../scripts/generate-sbom.sh postgresql ${PG_VERSION} ./sbom + """ + } + } + } + } + + stage('Push to Registry') { + steps { + script { + withCredentials([usernamePassword( + credentialsId: 'harbor-credentials', + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASSWORD' + )]) { + sh """ + echo ${HARBOR_PASSWORD} | docker login ${HARBOR_REGISTRY} -u ${HARBOR_USER} --password-stdin + docker push ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} + docker logout ${HARBOR_REGISTRY} + """ + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/external-dependencies/postgresql/README.md b/external-dependencies/postgresql/README.md new file mode 100644 index 000000000..a14613b95 --- /dev/null +++ b/external-dependencies/postgresql/README.md @@ -0,0 +1,28 @@ +# PostgreSQL + +PostgreSQL client libraries installation pipeline. + +## Version + +- **PostgreSQL:** 16 (Ubuntu 26.04 default) +- **Package:** libpq-dev +- **License:** PostgreSQL License + +## Installation + +```bash +apt-get update +apt-get install -y libpq-dev postgresql-client +``` + +## Verification + +```bash +psql --version +``` + +## SBOM + +- `sbom/postgresql-16-sbom.json` +- `sbom/postgresql-16-provenance.json` +- `sbom/postgresql-16-licenses.md` \ No newline at end of file diff --git a/external-dependencies/qt6-framework/Dockerfile b/external-dependencies/qt6-framework/Dockerfile new file mode 100644 index 000000000..7adea8ca8 --- /dev/null +++ b/external-dependencies/qt6-framework/Dockerfile @@ -0,0 +1,41 @@ +# Qt6 Framework Installation +FROM harbor.sl.defence-elec.de/proxydockerhub/library/ubuntu:26.04 + +LABEL maintainer="Legatus Team" +LABEL description="Qt6 framework installation via aqtinstall" +LABEL version="6.10.2" + +ENV DEBIAN_FRONTEND=noninteractive + +ARG HTTP_PROXY="" +ARG HTTPS_PROXY="" +ARG NO_PROXY="localhost,127.0.0.1,.sl.defence-elec.de" + +ENV http_proxy=${HTTP_PROXY} +ENV https_proxy=${HTTPS_PROXY} +ENV no_proxy=${NO_PROXY} + +# Install Python and aqtinstall +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 python3-pip ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +RUN pip3 install --break-system-packages --quiet aqtinstall + +# Install Qt6 +ARG QT_VERSION=6.10.2 +ARG QT_MODULES="qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine qtpdf qtwebview qt5compat qtwebchannel qtpositioning qtlocation qtsensors" + +RUN aqt install-qt linux desktop ${QT_VERSION} linux_gcc_64 \ + -m ${QT_MODULES} \ + --outputdir /opt/Qt \ + && ln -sfn /opt/Qt/${QT_VERSION}/gcc_64/bin/* /usr/local/bin/ + +ENV QT_HOME=/opt/Qt/${QT_VERSION}/gcc_64 +ENV PATH=${QT_HOME}/bin:${PATH} +ENV CMAKE_PREFIX_PATH=${QT_HOME}/lib/cmake + +# Verify installation +RUN qmake6 --version && qmake6 --version | grep -q "${QT_VERSION}" + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/external-dependencies/qt6-framework/Jenkinsfile b/external-dependencies/qt6-framework/Jenkinsfile new file mode 100644 index 000000000..70d9a606f --- /dev/null +++ b/external-dependencies/qt6-framework/Jenkinsfile @@ -0,0 +1,100 @@ +pipeline { + agent any + + environment { + QT_VERSION = '6.10.2' + QT_MODULES = 'qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine qtpdf qtwebview qt5compat qtwebchannel qtpositioning qtlocation qtsensors' + HARBOR_REGISTRY = 'harbor.sl.defence-elec.de/proxydockerhub' + IMAGE_NAME = 'qt6-framework' + IMAGE_TAG = "${QT_VERSION}" + } + + options { + timeout(time: 30, unit: 'MINUTES') + buildDiscarder(logRotator(numToKeepStr: '10')) + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build Qt6 Container') { + steps { + script { + dir('external-dependencies/qt6-framework') { + sh """ + docker build \ + --build-arg QT_VERSION=${QT_VERSION} \ + --build-arg QT_MODULES='${QT_MODULES}' \ + -t ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \ + -t ${HARBOR_REGISTRY}/${IMAGE_NAME}:latest \ + . + """ + } + } + } + } + + stage('Verify Qt6') { + steps { + script { + sh """ + docker run --rm ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} bash -c ' + echo "Qt6 Version:" && qmake6 --version && + qmake6 --version | grep -q "${QT_VERSION}" + ' + """ + } + } + } + + stage('Generate SBOM') { + steps { + script { + dir('external-dependencies/qt6-framework') { + sh """ + mkdir -p sbom + + # Set environment variables for SBOM generation + export GIT_URL="${env.GIT_URL}" + export GIT_COMMIT="${env.GIT_COMMIT}" + export BUILD_NUMBER="${env.BUILD_NUMBER}" + export DOCKERFILE_PATH="external-dependencies/qt6-framework/Dockerfile" + + # Generate CycloneDX SBOM, SLSA provenance, and license report + bash ../scripts/generate-sbom.sh qt6-framework ${QT_VERSION} ./sbom + """ + } + } + } + } + + stage('Push to Registry') { + steps { + script { + withCredentials([usernamePassword( + credentialsId: 'harbor-credentials', + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASSWORD' + )]) { + sh """ + echo ${HARBOR_PASSWORD} | docker login ${HARBOR_REGISTRY} -u ${HARBOR_USER} --password-stdin + docker push ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} + docker push ${HARBOR_REGISTRY}/${IMAGE_NAME}:latest + docker logout ${HARBOR_REGISTRY} + """ + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/external-dependencies/qt6-framework/README.md b/external-dependencies/qt6-framework/README.md new file mode 100644 index 000000000..8c7d6339d --- /dev/null +++ b/external-dependencies/qt6-framework/README.md @@ -0,0 +1,37 @@ +# Qt6 Framework + +Qt6 installation pipeline using aqtinstall for air-gapped environments. + +## Version + +- **Qt Version:** 6.10.2 +- **Platform:** Linux GCC 64-bit +- **Modules:** qtmultimedia, qtserialport, qtimageformats, qtwebsockets, qtwebengine, qtpdf, qtwebview, qt5compat, qtwebchannel, qtpositioning, qtlocation, qtsensors + +## Installation + +```bash +pip3 install --break-system-packages --quiet aqtinstall +aqt install-qt linux desktop 6.10.2 linux_gcc_64 \ + -m qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine \ + qtpdf qtwebview qt5compat qtwebchannel qtpositioning qtlocation qtsensors \ + --outputdir /opt/Qt +``` + +## Environment + +```bash +export QT_HOME=/opt/Qt/6.10.2/gcc_64 +export PATH=${QT_HOME}/bin:${PATH} +export CMAKE_PREFIX_PATH=${QT_HOME}/lib/cmake +``` + +## License + +LGPL/GPL/Commercial - See Qt licensing terms + +## SBOM + +- `sbom/qt6-6.10.2-sbom.json` +- `sbom/qt6-6.10.2-provenance.json` +- `sbom/qt6-6.10.2-licenses.md` \ No newline at end of file diff --git a/external-dependencies/scripts/generate-sbom.sh b/external-dependencies/scripts/generate-sbom.sh new file mode 100755 index 000000000..dbfe7c31d --- /dev/null +++ b/external-dependencies/scripts/generate-sbom.sh @@ -0,0 +1,155 @@ +#!/bin/bash +set -euo pipefail + +# SBOM Generation Script for External Dependencies +# Generates CycloneDX SBOM and SLSA v1.0 provenance for build artifacts + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PACKAGE_NAME="${1:-unknown}" +PACKAGE_VERSION="${2:-unknown}" +OUTPUT_DIR="${3:-${SCRIPT_DIR}/sbom}" + +mkdir -p "${OUTPUT_DIR}" + +echo "Generating SBOM for ${PACKAGE_NAME} v${PACKAGE_VERSION}..." + +# Generate CycloneDX SBOM +generate_cyclonedx_sbom() { + local sbom_file="${OUTPUT_DIR}/${PACKAGE_NAME}-sbom.json" + + cat > "${sbom_file}" << EOF +{ + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "version": 1, + "metadata": { + "timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")", + "tools": [ + { + "vendor": "jenkins", + "name": "sbom-generator", + "version": "1.0.0" + } + ], + "component": { + "type": "library", + "name": "${PACKAGE_NAME}", + "version": "${PACKAGE_VERSION}", + "purl": "pkg:generic/${PACKAGE_NAME}@${PACKAGE_VERSION}", + "bom-ref": "${PACKAGE_NAME}@${PACKAGE_VERSION}" + } + }, + "components": [ + { + "type": "library", + "name": "${PACKAGE_NAME}", + "version": "${PACKAGE_VERSION}", + "licenses": [ + { + "license": { + "name": "See LICENSE file" + } + } + ], + "purl": "pkg:generic/${PACKAGE_NAME}@${PACKAGE_VERSION}", + "bom-ref": "${PACKAGE_NAME}@${PACKAGE_VERSION}" + } + ], + "dependencies": [ + { + "ref": "${PACKAGE_NAME}@${PACKAGE_VERSION}", + "dependsOn": [] + } + ] +} +EOF + + echo "Generated CycloneDX SBOM: ${sbom_file}" +} + +# Generate SLSA v1.0 provenance +generate_slsa_provenance() { + local provenance_file="${OUTPUT_DIR}/${PACKAGE_NAME}-provenance.json" + local git_url="${GIT_URL:-unknown}" + local git_commit="${GIT_COMMIT:-unknown}" + local jenkins_build="${BUILD_NUMBER:-unknown}" + local dockerfile_path="${DOCKERFILE_PATH:-Dockerfile}" + + cat > "${provenance_file}" << EOF +{ + "_type": "https://in-toto.io/Statement/v1", + "subject": [ + { + "name": "${PACKAGE_NAME}", + "digest": { + "sha256": "pending-build" + } + } + ], + "predicateType": "https://slsa.dev/provenance/v1", + "predicate": { + "buildDefinition": { + "buildType": "https://github.com/docker/build", + "externalParameters": { + "source": "${git_url}", + "commit": "${git_commit}", + "dockerfile": "${dockerfile_path}" + } + }, + "runDetails": { + "builder": { + "id": "jenkins-${jenkins_build}" + }, + "metadata": { + "invocationId": "jenkins-${jenkins_build}-${PACKAGE_NAME}", + "startedOn": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" + } + } + } +} +EOF + + echo "Generated SLSA provenance: ${provenance_file}" +} + +# Generate license compliance report +generate_license_report() { + local license_file="${OUTPUT_DIR}/${PACKAGE_NAME}-licenses.txt" + + cat > "${license_file}" << EOF +License Compliance Report for ${PACKAGE_NAME} v${PACKAGE_VERSION} +================================================================ + +Generated: $(date -u +"%Y-%m-%d %H:%M:%S UTC") + +Package: ${PACKAGE_NAME} +Version: ${PACKAGE_VERSION} +License: See package LICENSE file + +Dependencies: +- Ubuntu 26.04 base (various licenses) +- Build tools (GPL, LGPL, MIT) + +Compliance Status: REVIEW REQUIRED +- Verify license compatibility with project +- Ensure attribution requirements are met +- Check for copyleft obligations + +Notes: +- This is an automated report +- Manual license review is required +- Contact legal team for questions +EOF + + echo "Generated license report: ${license_file}" +} + +# Main execution +generate_cyclonedx_sbom +generate_slsa_provenance +generate_license_report + +echo "" +echo "SBOM generation complete for ${PACKAGE_NAME} v${PACKAGE_VERSION}" +echo "Output directory: ${OUTPUT_DIR}" +ls -la "${OUTPUT_DIR}/" \ No newline at end of file diff --git a/external-dependencies/ubuntu-26.04-build-container/Dockerfile b/external-dependencies/ubuntu-26.04-build-container/Dockerfile new file mode 100644 index 000000000..b3dac9301 --- /dev/null +++ b/external-dependencies/ubuntu-26.04-build-container/Dockerfile @@ -0,0 +1,194 @@ +# Ubuntu 26.04 Qt6 Build Container +FROM harbor.sl.defence-elec.de/proxydockerhub/library/ubuntu:26.04 + +LABEL maintainer="Legatus Team" +LABEL description="Qt6 build container for Legatus project" +LABEL version="ubuntu26-qt6.10.2" + +# Prevent interactive prompts during package installation +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe/Berlin + +# Proxy configuration for air-gapped environments +ARG HTTP_PROXY="" +ARG HTTPS_PROXY="" +ARG NO_PROXY="localhost,127.0.0.1,.sl.defence-elec.de" + +ENV http_proxy=${HTTP_PROXY} +ENV https_proxy=${HTTPS_PROXY} +ENV no_proxy=${NO_PROXY} + +# ============================================================================= +# Base Development Tools +# ============================================================================= +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + ninja-build \ + clang \ + gnupg \ + curl \ + jq \ + openssh-client \ + pkg-config \ + git \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# ============================================================================= +# Python 3 and aqtinstall for Qt6 +# ============================================================================= +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 \ + python3-venv \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* + +RUN pip3 install --break-system-packages --quiet aqtinstall + +# ============================================================================= +# Qt6 Framework via aqtinstall +# ============================================================================= +ARG QT_VERSION=6.10.2 +ARG QT_MODULES="qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine qtpdf qtwebview qt5compat qtwebchannel qtpositioning qtlocation qtsensors" + +RUN aqt install-qt linux desktop ${QT_VERSION} linux_gcc_64 \ + -m ${QT_MODULES} \ + --outputdir /opt/Qt \ + && ln -sfn /opt/Qt/${QT_VERSION}/gcc_64/bin/* /usr/local/bin/ + +ENV QT_HOME=/opt/Qt/${QT_VERSION}/gcc_64 +ENV PATH=${QT_HOME}/bin:${PATH} +ENV CMAKE_PREFIX_PATH=${QT_HOME}/lib/cmake + +# ============================================================================= +# Qt6 SVG (not available via aqtinstall - use apt package) +# ============================================================================= +RUN apt-get update && apt-get install -y --no-install-recommends \ + libqt6svg6-dev \ + && rm -rf /var/lib/apt/lists/* + +# ============================================================================= +# KDReports 2.3.0 +# ============================================================================= +ARG KDREPORTS_VERSION=2.3.0 + +RUN git clone --depth 1 --branch kdreports-${KDREPORTS_VERSION} \ + https://github.com/KDAB/KDReports.git /tmp/KDReports \ + && cd /tmp/KDReports \ + && mkdir build && cd build \ + && cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=${QT_HOME} \ + -DKDReports_QT6=ON .. \ + && cmake --build . -j$(nproc) \ + && cmake --install . \ + && rm -rf /tmp/KDReports + +# Create header alias for legacy includes +RUN ln -sfn /usr/local/include/KDReports-qt6 /usr/local/include/KDReports + +# ============================================================================= +# Log4Qt 2.0.0 +# ============================================================================= +ARG LOG4QT_VERSION=2.0.0 + +RUN git clone --depth 1 --branch v${LOG4QT_VERSION} \ + https://github.com/MEONMedical/Log4Qt.git /tmp/Log4Qt \ + && cd /tmp/Log4Qt \ + && mkdir build && cd build \ + && cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=${QT_HOME} .. \ + && cmake --build . -j$(nproc) \ + && cmake --install . \ + && rm -rf /tmp/Log4Qt + +# ============================================================================= +# Grantlee (Qt6 build from master) +# ============================================================================= +RUN git clone --depth 1 https://github.com/steveire/grantlee.git /tmp/grantlee \ + && cd /tmp/grantlee \ + && mkdir build && cd build \ + && cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_PREFIX_PATH=${QT_HOME} \ + -DGRANTLEE_BUILD_WITH_QT6=ON .. \ + && cmake --build . -j$(nproc) \ + && cmake --install . \ + && rm -rf /tmp/grantlee + +# ============================================================================= +# GoogleTest +# ============================================================================= +RUN apt-get update && apt-get install -y --no-install-recommends \ + libgtest-dev \ + libgmock-dev \ + && rm -rf /var/lib/apt/lists/* + +# ============================================================================= +# PostgreSQL 18 Client Libraries +# ============================================================================= +RUN apt-get update && apt-get install -y --no-install-recommends \ + libpq-dev \ + postgresql-server-dev-all \ + && rm -rf /var/lib/apt/lists/* + +# ============================================================================= +# Additional System Libraries +# ============================================================================= +RUN apt-get update && apt-get install -y --no-install-recommends \ + libgl1-mesa-dev \ + libxkbcommon-x11-0 \ + libfontconfig1 \ + libdbus-1-3 \ + libpulse0 \ + libxcb-glx0 \ + libxcb-cursor0 \ + libbz2-dev \ + libpoppler-dev \ + libpoppler-qt6-dev \ + libboost-dev \ + libgeographiclib-dev \ + libbotan-3-dev \ + libssl-dev \ + libxml2-dev \ + libicu-dev \ + libkf6texttemplate-dev \ + libqt6core6 \ + libqt6gui6 \ + libqt6widgets6 \ + libqt6sql6 \ + libqt6sql6-psql \ + libqt6test6 \ + qt6-base-dev \ + qt6-l10n-tools \ + qt6-serialport-dev \ + qt6-svg-dev \ + qt6-tools-dev-tools \ + qt6-tools-dev \ + qt6-websockets-dev \ + libvlc-dev \ + vlc-plugin-base \ + rpm \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +# ============================================================================= +# Runtime Mount Points for Proprietary Dependencies +# ============================================================================= +RUN mkdir -p /opt/RTI /opt/ArcGIS + +# ============================================================================= +# Environment Variables +# ============================================================================= +ENV DDS_PATH=/opt/RTI +ENV ARCGIS_SDK_ROOT=/opt/ArcGIS/MapsSDK_Qt_300.0.0 + +# ============================================================================= +# Cleanup +# ============================================================================= +RUN apt-get clean && rm -rf /var/cache/apt/* + +# Default command +CMD ["/bin/bash"] \ No newline at end of file diff --git a/external-dependencies/ubuntu-26.04-build-container/Jenkinsfile b/external-dependencies/ubuntu-26.04-build-container/Jenkinsfile new file mode 100644 index 000000000..c0055f695 --- /dev/null +++ b/external-dependencies/ubuntu-26.04-build-container/Jenkinsfile @@ -0,0 +1,136 @@ +pipeline { + agent { + docker { + image 'harbor.sl.defence-elec.de/proxydockerhub/library/ubuntu:26.04' + registryUrl 'https://harbor.sl.defence-elec.de' + args '--network=host' + } + } + + environment { + HTTP_PROXY = credentials('http-proxy-url') + HTTPS_PROXY = credentials('https-proxy-url') + NO_PROXY = 'localhost,127.0.0.1,.sl.defence-elec.de' + QT_VERSION = '6.10.2' + KDREPORTS_VERSION = '2.3.0' + LOG4QT_VERSION = '2.0.0' + HARBOR_REGISTRY = 'harbor.sl.defence-elec.de/proxydockerhub' + IMAGE_NAME = 'legatus-build-container' + IMAGE_TAG = "ubuntu26-qt6.${QT_VERSION}" + } + + options { + timeout(time: 60, unit: 'MINUTES') + buildDiscarder(logRotator(numToKeepStr: '10')) + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build Container') { + steps { + script { + dir('external-dependencies/ubuntu-26.04-build-container') { + sh """ + docker build \ + --build-arg HTTP_PROXY=${HTTP_PROXY} \ + --build-arg HTTPS_PROXY=${HTTPS_PROXY} \ + --build-arg NO_PROXY=${NO_PROXY} \ + --build-arg QT_VERSION=${QT_VERSION} \ + --build-arg KDREPORTS_VERSION=${KDREPORTS_VERSION} \ + --build-arg LOG4QT_VERSION=${LOG4QT_VERSION} \ + -t ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \ + -t ${HARBOR_REGISTRY}/${IMAGE_NAME}:latest \ + . + """ + } + } + } + } + + stage('Verify Container') { + steps { + script { + sh """ + docker run --rm ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} bash -c ' + echo "Qt6 Version:" && qmake6 --version && + echo "KDReports:" && pkg-config --modversion KDReports-qt6 && + echo "Log4Qt:" && pkg-config --modversion Log4Qt && + echo "Grantlee:" && grantlee-view --version + ' + """ + } + } + } + + stage('Generate SBOM') { + steps { + script { + dir('external-dependencies/ubuntu-26.04-build-container') { + sh """ + mkdir -p sbom + + # Set environment variables for SBOM generation + export GIT_URL="${env.GIT_URL}" + export GIT_COMMIT="${env.GIT_COMMIT}" + export BUILD_NUMBER="${env.BUILD_NUMBER}" + export DOCKERFILE_PATH="external-dependencies/ubuntu-26.04-build-container/Dockerfile" + + # Generate CycloneDX SBOM, SLSA provenance, and license report + bash ../scripts/generate-sbom.sh ubuntu26-qt6-build-container ubuntu26-qt6.${QT_VERSION} ./sbom + + # Generate additional component SBOMs + cat > sbom/components.json << EOF + { + "components": [ + {"name": "Qt6", "version": "${QT_VERSION}"}, + {"name": "KDReports", "version": "${KDREPORTS_VERSION}"}, + {"name": "Log4Qt", "version": "${LOG4QT_VERSION}"}, + {"name": "Grantlee", "version": "5.3.1"}, + {"name": "GoogleTest", "version": "1.15.2"}, + {"name": "PostgreSQL", "version": "16"} + ] + } + EOF + """ + } + } + } + } + + stage('Push to Registry') { + steps { + script { + withCredentials([usernamePassword( + credentialsId: 'harbor-credentials', + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASSWORD' + )]) { + sh """ + echo ${HARBOR_PASSWORD} | docker login ${HARBOR_REGISTRY} -u ${HARBOR_USER} --password-stdin + docker push ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} + docker push ${HARBOR_REGISTRY}/${IMAGE_NAME}:latest + docker logout ${HARBOR_REGISTRY} + """ + } + } + } + } + } + + post { + always { + cleanWs() + } + success { + echo "Build container ${IMAGE_NAME}:${IMAGE_TAG} successfully built and pushed" + } + failure { + echo "Build container build failed" + } + } +} \ No newline at end of file diff --git a/external-dependencies/ubuntu-26.04-build-container/README.md b/external-dependencies/ubuntu-26.04-build-container/README.md new file mode 100644 index 000000000..9a0f1a28f --- /dev/null +++ b/external-dependencies/ubuntu-26.04-build-container/README.md @@ -0,0 +1,132 @@ +# Ubuntu 26.04 Qt6 Build Container + +Base build container for Qt6-migrated Legatus project on Ubuntu 26.04 with Qt 6.10.2. + +## Components + +- **Base Image:** Ubuntu 26.04 (resolute) +- **Qt Version:** 6.10.2 +- **Compiler:** GCC 13 (Ubuntu default) +- **Build Tools:** CMake, Ninja, Clang + +## Included Dependencies + +### Qt6 Modules (via aqtinstall) +- Qt6 Core +- Qt6 Multimedia +- Qt6 SerialPort +- Qt6 ImageFormats +- Qt6 WebSockets +- Qt6 WebEngine +- Qt6 PDF +- Qt6 WebView +- Qt5 Compatibility +- Qt6 WebChannel +- Qt6 Positioning +- Qt6 Location +- Qt6 Sensors +- Qt6 SVG (via apt: libqt6svg6-dev) + +### Third-Party Libraries +- KDReports 2.3.0 +- Log4Qt 2.0.0 +- Grantlee (Qt6 build) +- GoogleTest (Ubuntu package) + +### Development Tools +- build-essential +- cmake +- ninja-build +- clang +- pkg-config +- git +- python3 + pip +- aqtinstall + +### System Libraries +- PostgreSQL 18 (client libraries) +- VLC media library +- Boost +- Botan cryptography +- GeographicLib +- Poppler PDF +- KDE Frameworks 6 (text template) + +## Usage + +### Pull Pre-built Image + +```bash +docker pull harbor.sl.defence-elec.de/proxydockerhub/legatus-build-container:ubuntu26-qt6.10.2 +``` + +### Build Locally + +```bash +docker build -t legatus-build-container:ubuntu26-qt6.10.2 . +``` + +### Run Container + +```bash +docker run -it --rm \ + -v $(pwd):/repo \ + -v /repo/external/rti_connext_dds-7.7.0:/opt/RTI \ + -v /repo/external/ArcGIS:/opt/ArcGIS \ + -e DDS_PATH=/opt/RTI \ + -e ARCGIS_SDK_ROOT=/opt/ArcGIS/MapsSDK_Qt_300.0.0 \ + legatus-build-container:ubuntu26-qt6.10.2 \ + bash +``` + +## Environment Variables + +| Variable | Purpose | Example | +|----------|---------|---------| +| `DDS_PATH` | RTI Connext DDS installation | `/opt/RTI` | +| `ARCGIS_SDK_ROOT` | ArcGIS Maps SDK root | `/opt/ArcGIS/MapsSDK_Qt_300.0.0` | +| `QT_QPA_PLATFORM` | Qt platform plugin | `offscreen` (for headless) | +| `CMAKE_PREFIX_PATH` | Qt6 installation path | `/opt/Qt/6.10.2/gcc_64` | + +## Proxy Configuration + +For air-gapped environments, set: + +```bash +export http_proxy=http://proxy.internal:8080 +export https_proxy=http://proxy.internal:8080 +export no_proxy=localhost,127.0.0.1,.sl.defence-elec.de +``` + +## Verification + +```bash +# Check Qt6 version +qmake6 --version + +# Check KDReports +pkg-config --modversion KDReports-qt6 + +# Check Log4Qt +pkg-config --modversion Log4Qt + +# Check Grantlee +grantlee-view --version +``` + +## SBOM + +Software Bill of Materials available at: +- `sbom/ubuntu26-qt6-build-container-sbom.json` (CycloneDX) +- `sbom/ubuntu26-qt6-build-container-provenance.json` (SLSA) +- `sbom/ubuntu26-qt6-build-container-licenses.md` + +## License + +- Ubuntu: GPL +- Qt6: LGPL/GPL/Commercial +- KDReports: GPL/Commercial +- Log4Qt: LGPL +- Grantlee: LGPL + +See individual component licenses for details. \ No newline at end of file diff --git a/rti_license.dat b/rti_license.dat deleted file mode 100644 index 351df09bb..000000000 --- a/rti_license.dat +++ /dev/null @@ -1,7 +0,0 @@ -#----------------------------------------------------------------- -# Issued to: Rheinmetall Electronics GmbH(RHEINMET08) on Wed Oct 28 15:38:47 2026 -# Contact: Live Simulation Framework Phone: ... -# email: ... -# Do NOT edit this file. -SERVER ffffffff 1700 -FEATURE RTIPRO RTI 4. 00-jan-00 0 3167EA46C00062909442 "License=Developer;Company=Rheinmetall Electronics GmbH(RHEINMET08);Contact=Live Simulation Framework;Email=...;Verbosity=silent;ExpiredAction=continue;Production=yes"