Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,6 @@ docker-compose*.yml
# Temporary files
*.tmp
*.temp

# AI Tools
.claude/
12 changes: 11 additions & 1 deletion .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,17 @@ jobs:
run: dnf -y update fedora-gpg-keys

- name: Install git and Python libraries
run: dnf -y install git-core python3-yaml python3-jinja2 python3-koji python3-pytest python3-flake8 python3-dnf
run: |
dnf -y install \
git-core \
python3-flake8 \
python3-jinja2 \
python3-koji \
python3-libdnf5 \
python3-pip \
python3-pytest \
python3-pytest-cov \
python3-yaml

- name: Clean up
run: dnf clean all
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/fork-only-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ jobs:
run: |
dnf -y install \
git \
python3-flake8 \
python3-jinja2 \
python3-koji \
python3-yaml \
python3-dnf \
python3-libdnf5 \
python3-pytest \
python3-flake8
python3-pytest-cov \
python3-yaml

- name: Clean up
run: dnf clean all
Expand Down
9 changes: 6 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# IDE and editor files
.idea
.vscode
.idea/
.vscode/
*.swp

# Python cache and bytecode
Expand All @@ -24,4 +24,7 @@ pkg_entries.json
actual_output
actual_configs
content-resolver-input
debug_*.json
debug_*.json

# AI Tools
.claude/
13 changes: 11 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
FROM registry.fedoraproject.org/fedora:44

RUN dnf -y update fedora-gpg-keys && \
dnf -y install git python3-jinja2 python3-koji python3-yaml python3-dnf && \
RUN dnf -y update fedora-gpg-keys \
--setopt=tsflags=nodocs \
--setopt=install_weak_deps=False && \
dnf -y install \
git \
python3-jinja2 \
python3-koji \
python3-libdnf5 \
python3-yaml \
--setopt=tsflags=nodocs \
--setopt=install_weak_deps=False && \
dnf clean all && \
rm -rf /var/cache/dnf

Expand Down
84 changes: 83 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Content Resolver

Content Resolver makes it easy to define and inspect package sets of RPM-based Linux distribution.
[![Content Resolver CI](https://github.com/fedora-eln/content-resolver/actions/workflows/docker-image.yml/badge.svg)](https://github.com/fedora-eln/content-resolver/actions/workflows/docker-image.yml)

Content Resolver makes it easy to define and inspect package sets of RPM-based Linux distributions.

You define what packages you need, and Content Resolver gives you the whole picture including all the dependencies. And it keeps it up-to-date as packages get updated over time.

Expand All @@ -12,6 +14,28 @@ Content Resolver also helps with minimisation efforts by showing detailed depend

## Using Content Resolver

### Code Structure

Core functionality

```
content-resolver/
├── content_resolver/
│ ├── analyzer.py # Core resolution engine (DNF5)
│ ├── config_manager.py # YAML config loading
│ ├── data_generation.py # Generate non HTML output
│ ├── exceptions.py # Custom exceptions
│ ├── history_data.py # Handle history for graph generation
│ ├── page_generation.py # Generate HTML output
│ ├── query.py # Internal data query mechanism
│ └── utils.py # Helper functions
├── templates/ # Jinja2 HTML templates
├── test_configs/ # Test configurations
├── content_resolver.py # Main entry point
└── refresh.sh # Production deployment script
```


### Controlling Content Resolver

Content Resolver is entirely controlled by a set of YAML files stored in a git repository. Changes to the content can easily be modified and reviewed via pull requests.
Expand Down Expand Up @@ -144,3 +168,61 @@ $ docker run --rm -it --tmpfs /dnf_cachedir -v $(pwd):/workspace content-resolve
```

The output will be generated in the `output` directory. Open the `output/index.html` in your web browser of choice to see the result.

### Resolution Process

**Phase 1: Repository Analysis**
```
For each repository and architecture:
1. Create DNF5 Base with repository configuration
2. Apply repository priorities (1=highest)
3. Apply package exclude lists (e.g., rust-*-devel, golang-*-devel)
4. Load repository metadata
5. Query all available packages
6. Deduplicate by NEVRA (Name-Epoch:Version-Release.Arch)
7. Track which repo provides each package
```

**Phase 2: Environment Resolution**
```
For each environment:
1. Create DNF5 Goal with environment packages
2. Resolve dependencies using DNF5 transaction
3. Check transaction.get_problems() for conflicts
4. Extract installed packages (base environment)
5. Build package relationship graph
```

**Phase 3: Workload Resolution**
```
For each workload on top of each environment:
1. Load base environment packages
2. Add workload-specific packages to Goal
3. Resolve additional dependencies
4. Separate environment packages from added packages
5. Track which workloads require which packages
```

**Phase 4: Buildroot Resolution** (for views with `buildroot_strategy: root_logs`)
```
For each source package in the view:
1. Download Koji root.log via Koji API
2. Parse build dependencies from root log
3. Create fake workload with build dependencies
4. Resolve buildroot on top of build group
5. Track buildroot packages separately from runtime
6. Iterate until all transitive build deps resolved
```

### Repository Priority System

Repositories are assigned priorities (1=highest, 5=lowest) to control package selection when multiple versions exist:

```yaml
BaseOS: priority: 1 # Prefer packages from BaseOS
AppStream: priority: 1 # Prefer packages from AppStream
CRB: priority: 1 # CodeReady Builder
Extras: priority: 3 # Additional packages
buildroot: priority: 4 # Build-time only packages
Rawhide: priority: 5 # Fallback for missing packages
```
5 changes: 3 additions & 2 deletions content_resolver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
# https://docs.python.org/3/whatsnew/3.14.html#concurrent-futures

import multiprocessing

try:
multiprocessing.set_start_method('fork')
except RuntimeError as err:
multiprocessing.set_start_method("fork")
except RuntimeError:
# Already set, ignore
pass
Loading