# Multiple Package Repo Support
A major feature of the OS Image Composer tool is its ability to let you add
multiple package repositories to the OS build. These repositories often contain
in-house proprietary packages or upstream packages pending integration. By
supporting multiple repositories, the tool enables rapid deployment,
experimentation, and validation of custom software alongside standard OS
components. This document describes the key aspects of the multiple package repo:
- **Configuration**: Describes how to add and configure extra package
repositories, enabling the OS Image Composer tool to access and pull custom
packages that are unavailable in the base repository.
- **Package conflict priority consideration**: Outlines how the tool determines
which package to use when duplicates exist across repositories, prioritizing
the user-specified order and base repository integrity.
- **Architectural design**: Describes how the design extends the tool's package
and dependency pre-download framework to resolve dependencies without relying
on package managers like APT or
[tdnf](https://github.com/vmware/tdnf).
## Table of Contents
- [Setting Multiple Repositories in the User Template](#setting-multiple-repositories-in-the-user-template)
- [Package Conflict Priority Consideration](#package-conflict-priority-consideration)
- [Priority Rules](#priority-rules)
- [Resolution Process](#resolution-process)
- [Conflict Resolution Examples](#conflict-resolution-examples)
- [Example 1: Different versions across repositories](#example-1-different-versions-across-repositories)
- [Example 2: Same version in multiple repositories](#example-2-same-version-in-multiple-repositories)
- [Example 3: Mixed scenario](#example-3-mixed-scenario)
- [Dependencies Package](#dependencies-package)
- [Dependency Resolution in a Multi-Repository Environment](#dependency-resolution-in-a-multi-repository-environment)
- [Dependency Resolution Rules](#dependency-resolution-rules)
- [Dependency Resolution Examples](#dependency-resolution-examples)
- [Example 1: Parent package with dependencies](#example-1-parent-package-with-dependencies)
- [Example 2: Transitive dependencies](#example-2-transitive-dependencies)
- [Example 3: Fallback to base repository](#example-3-fallback-to-base-repository)
- [Example 4: Unresolvable dependency](#example-4-unresolvable-dependency)
- [Example 5: Conflicting dependency versions](#example-5-conflicting-dependency-versions)
- [Benefits of Repository Affinity](#benefits-of-repository-affinity)
- [Architectural Design](#architectural-design)
- [Single Repository Support](#single-repository-support)
- [Multiple Repositories Support](#multiple-repositories-support)
- [Multiple Repository Flow](#multiple-repository-flow)
- [Related Documentation](#related-documentation)
## Setting Multiple Repositories in the User Template
You can specify additional package repositories in the OS Image Composer user
template. Here's an example:
```yaml
...
additionalrepo:
intel1: "https://www.intel.com/repo1" # Add new package repo URL
intel2: "https://www.intel.com/repo2" # Add another new package repo URL
packages:
- intelpackage01 # Package from intel1 repo
- intelpackage02 # Package from intel2 repo
- systemd-boot # Package from base repo
...
```
Each repository must follow the standard Debian or RPM structure, including all
required metadata. The OS Image Composer tool performs sanity checks to ensure
repository URLs are valid before proceeding. See the following repository
setup references:
- Debian repo setup: https://wiki.debian.org/DebianRepository/Setup
- RPM repo setup: https://wiki.centos.org/HowTos/CreateLocalRepos
## Package Conflict Priority Consideration
When multiple repositories contain packages with the same name, the OS Image
Composer tool uses a simple two-rule priority system for package selection.
### Priority Rules
The OS Image Composer tool follows these straightforward rules to resolve
package conflicts:
1. **Version Priority**: If the same package exists in multiple repositories
with different versions, the tool always selects the package with the latest
version number, regardless of which repository contains it.
2. **Repository Order Priority**: If the same package exists in multiple
repositories with identical versions, the OS Image Composer tool follows
the following priority order:
- Base OS repository (highest priority)
- Additional repositories in the order they appear in configuration
### Resolution Process
Decision Flow:
1. Check if package versions differ → Select latest version
2. If versions are identical → Follow repository priority order:
- Base OS repository
- intel1 (first additional repo in config)
- intel2 (second additional repo in config)
- ... (subsequent repos in config order)
### Conflict Resolution Examples
#### Example 1: Different versions across repositories
- Base repo contains: `curl-7.68.0`
- intel1 repo contains: `curl-8.0.1`
- **Result**: The tool selects `curl-8.0.1` from intel1 (latest version rule).
#### Example 2: Same version in multiple repositories
- Base repo contains: `mypackage-1.0.0`
- intel1 repo contains: `mypackage-1.0.0`
- intel2 repo contains: `mypackage-1.0.0`
- **Result**: The tool selects `mypackage-1.0.0` from base repo (repository
order priority).
#### Example 3: Mixed scenario
- intel1 repo contains: `testpackage-2.0.0`
- intel2 repo contains: `testpackage-1.5.0`
- **Result**: The tool selects `testpackage-2.0.0` from intel1 (latest version
rule).
This simplified priority system ensures you always get the most recent package
versions while maintaining predictable behavior for identical versions.
### Dependencies Package
What are Dependencies? In simple terms, dependencies are other packages that a
software package needs to work properly. Think of it like cooking a recipe:
If you want to make a cake, you need ingredients like flour, eggs, and sugar.
Similarly, when you install a software package, it often needs other software
packages (dependencies) to function correctly.
Here are several examples: A web browser might depend on graphics libraries to
display images; a media player might depend on codec packages to play different
video formats; a database application might depend on networking libraries to
communicate over the internet.
#### Dependency Resolution in a Multi-Repository Environment
The OS Image Composer tool automatically resolves dependencies according to the
rules below, ensuring package consistency by keeping parent packages and their
dependencies from the same repository.
#### Dependency Resolution Rules
1. **Repository Affinity**: Dependencies are always pulled from the same
repository as their parent package, regardless of newer versions available
in other repositories.
2. **Fallback to Base Repository**: If a dependency cannot be resolved within
the same repository as the parent package (i.e., it was not found at all),
the tool will attempt to resolve the dependency from the base OS repository.
3. **Conflict Prevention**: This approach prevents version mismatches and
compatibility issues that could arise from mixing dependencies across
different repositories.
4. **Single Version Enforcement**: If different packages require different
versions of the same dependency (e.g., package A needs `libtest=0.1` and
package B needs `libtest=0.2`), the tool will fail with an error. Multiple
versions of the same dependency cannot be installed in parallel.
#### Dependency Resolution Examples
##### Example 1: Parent package with dependencies
- User specifies: `myapp-2.0.0` (available in intel1 repo)
- `myapp-2.0.0` depends on: `libssl-1.1.0` and `libcrypto-1.1.0`
- Base repo contains: `libssl-1.2.0` (newer version)
- intel1 repo contains: `libssl-1.1.0` and `libcrypto-1.1.0`
- **Result**: The tool pulls `libssl-1.1.0` and `libcrypto-1.1.0` from intel1
repo (same as parent).
##### Example 2: Transitive dependencies
- User specifies: `customtools-1.0.0` (from intel2 repo)
- `customtools-1.0.0` → depends on `libxml-2.0.0` (from intel2)
- `libxml-2.0.0` → depends on `zlib-1.2.5` (available in base repo as 1.2.8
and intel2 as 1.2.5)
- **Result**: All dependencies (`libxml-2.0.0`, `zlib-1.2.5`) are pulled from
the intel2 repo.
##### Example 3: Fallback to base repository
- User specifies: `specialpackage-1.0.0` (from intel1 repo)
- `specialpackage-1.0.0` depends on `missinglib-1.0.0`
- `missinglib-1.0.0` not available in intel1 repo but exists in base repo
- **Result**: The tool pulls `specialpackage-1.0.0` from intel1 repo and
`missinglib-1.0.0` from the base repo (fallback rule).
##### Example 4: Unresolvable dependency
- User specifies: `anotherpackage-2.0.0` (from intel2 repo)
- `anotherpackage-2.0.0` depends on `unknownlib-3.0.0`
- `unknownlib-3.0.0` not available in any repository
- **Result**: The tool reports dependency resolution failure and suggests
adding missing package to the relevant repository or using an alternative.
##### Example 5: Conflicting dependency versions
- User specifies: `packageA-1.0.0` (depends on `libtest=0.1`)
- User also specifies: `packageB-2.0.0` (depends on `libtest=0.2`)
- **Result**: The tool fails with an error—multiple versions of `libtest`
cannot be installed in parallel. You must resolve the conflict by choosing
compatible packages.
- **Alternative Solution**: If both versions of `libtest` are required, you
can package each version under a unique package name, such as `libtest01`
and `libtest02`. This approach allows both versions to co-exist and satisfy
the dependencies for different packages.
#### Benefits of Repository Affinity
- **Consistency**: Ensures all related packages come from the same tested source.
- **Compatibility**: Prevents version conflicts between interdependent packages.
- **Predictability**: Identifies exactly which repository provides your complete
package stack.
- **Maintainability**: Simplifies troubleshooting when issues arise with custom
packages.
This dependency-resolution strategy maintains package integrity while supporting
the multi-repository architecture.
## Architectural Design
The design integrates with the tool's package and dependency pre-download
framework for a single repository and then extends it to support
multiple packages.
### Single Repository Support
Here's a quick description of the single repository model so you can envision
how it extends to support multiple repositories, which are described in
the next section.
The core concept of the single repository model is to build a metadata list of
all available packages from a single repository, with this list only containing
one repo metadata, and using it as a database of sorts to validate user package
requests and resolve dependencies at each subsequence step. The high-level
single repositiory flow proceeds like this:
```mermaid
graph TD
A[Base Repo Metadata] --> B(full package list)
C[User Package List] --> D{Check if user list is available?}
B -- Pass full list --> D
B -- Pass full list --> E[Resolve dependencies]
D -- Yes --> E
D -- No --> F[Throw Error: User list not found]
E --> G["Create full download list
(user packages + dependencies)"]
G --> H[Download packages]
H --> I[Validate package signatures]
```
### Multiple Repositories Support
The enhanced design extends the tool's package and dependency pre-download
framework to support multiple repositories. Instead of building a metadata list
from a single source, the tool aggregates metadata from all the configured
repositories into a unified package database. This consolidated list enables
validation of user package requests and accurate dependency resolution across
repositories. The high-level flow remains similar, but now operates on combined
metadata to seamlessly support multiple repositories. The high-level flow is
described below.
### Multiple Repository Flow
```mermaid
graph TD
subgraph Repo Metadata Sources
A[Base Repo Metadata]
B[Customer Repo Metadata 1]
C[Customer Repo Metadata 2]
end
subgraph Process
D(Full package list with multiple repos)
E[User Package List]
F{Check if user list is available?}
G[Resolve dependencies and version conflicting]
H["Create full download list
(user packages + dependencies)"]
I[Download packages]
J[Validate package signatures]
end
subgraph Error Handling
K[Throw Error: User list not found]
end
A --> D
B --> D
C --> D
E --> F
D -- Pass full list --> F
D -- Pass full list --> G
F -- Yes --> G
F -- No --> K
G --> H
H --> I
I --> J
```
**Package manager independence** is a key benefit of this design: The tool's
package downloading framework remains independent from third-party package
managers, such as APT, DNF, and tdnf. The result delivers flexibility for
non-traditional requirements and future customizations.
## Related Documentation
- [Understanding the Build Process](./os-image-composer-build-process.md)
- [Understanding Templates](./os-image-composer-templates.md)
- [Multiple Package Repository Support](./os-image-composer-multi-repo-support.md)
- [OS Image Composer CLI Reference](./os-image-composer-cli-specification.md)