-
Notifications
You must be signed in to change notification settings - Fork 484
Distribution Support
The whole feature sits behind the :enhanced_distribution_support feature toggle.

The organisation that publishes distributions — openSUSE, SUSE, Debian.
A Vendor belongs to exactly one Project, and a Project has at most one Vendor (has_one :vendor, dependent: :destroy). That project is the vendor's home in OBS and the source of all authorization for the subtree beneath it. The one-to-one is enforced by a UNIQUE index on vendors.project_id.
Fields: name, description, url.
belongs_to :project, optional: false
has_many :distros, dependent: :destroyA product line published by a vendor — Leap, Tumbleweed, SLES, Debian.
Names are unique per vendor, not globally, so two vendors may both ship something called "Micro". Enforced both in the model and by a composite UNIQUE index on (vendor_id, name).
Fields: name, description, url.
belongs_to :vendor, optional: false
has_many :distro_releases, dependent: :destroy
has_one :project, through: :vendorA specific shipped version of a distro — Leap 15.6, SLES 15 SP6, Debian 13.
Names are unique per distro, via (distro_id, name). Fields: name, description, url.
belongs_to :distro, optional: false
has_many :distro_release_repository_architectures, dependent: :destroy
has_many :repository_architectures, through: :distro_release_repository_architectures
has_many :repositories, through: :repository_architectures
has_many :projects, through: :repositoriesThe join model that says what a release is actually made of. A release links to many RepositoryArchitectures, and one RepositoryArchitecture may serve many releases. A UNIQUE index on (distro_release_id, repository_architecture_id) keeps the pairing from being recorded twice.
OBS already has a Distribution model, and the new hierarchy deliberately does not reuse or extend it. The two solve different problems:
Distribution (legacy) |
Distribution Support | |
|---|---|---|
| Shape | Flat — vendor is a string column on each row |
Three linked models |
| Ownership | Admin-only (DistributionsController restricts create/update/destroy) |
Project maintainers, via the policy chain |
| Purpose | Populates the "Add repository" wizard | Describes what a vendor ships, and what it is built from |
Note the naming: the new model is Distro, not Distribution, precisely so the two can coexist. There is no namespace involved; the class names are distinct.
This is easy to get wrong in either direction.
Not projects. The obvious framing is "a release is a set of projects". This cannot express reality, because projects are shared across releases. openSUSE:Maintenance feeds several Leap versions simultaneously. Given only a project, there is no way to say which release a given piece of content belongs to.
Not repositories alone. Repository is still a set of architectures, and a release does not necessarily ship all of them. A repository may build x86_64, aarch64 and i586 while the release in question only ships the first two.
RepositoryArchitecture is the finest grain that is still a real, existing OBS object — it is the row that a build actually targets. Anchoring there means the composition of a release is exact, and the coarser views come for free by traversal.
repositories and projects on DistroRelease are conveniences reached through the join. If a release links three architectures of the same repository, that repository appears three times:
release.repositories.count # => 3, for one repository
release.repositories.distinct.count # => 1The same applies to projects, compounded — a project with two repositories at three arches each yields six rows. Always add .distinct when you want the set rather than the multiset, and treat both associations as read-only views; writes belong on repository_architectures.
Constraints are declared at both layers — model validation for usable error messages, database index for the actual guarantee.
| Table | Unique index | Foreign keys |
|---|---|---|
vendors |
(project_id) |
→ projects
|
distros |
(vendor_id, name) |
→ vendors
|
distro_releases |
(distro_id, name) |
→ distros
|
distro_release_repository_architectures |
(distro_release_id, repository_architecture_id) |
→ distro_releases, repository_architectures
|
Deletion cascades through dependent: :destroy at every level, so destroying a vendor removes its distros, their releases, and the join rows but never touches the RepositoryArchitecture records themselves, which belong to the repositories.
- Development Environment Overview
- Development Environment Tips & Tricks
- Spec-Tips
- Code Style
- Rubocop
- Testing with VCR
- Test in kanku
- Authentication
- Authorization
- Autocomplete
- BS Requests
- Events
- ProjectLog
- Notifications
- Feature Toggles
- Build Results
- Attrib classes
- Flags
- The BackendPackage Cache
- Maintenance classes
- Cloud uploader
- Delayed Jobs
- Staging Workflow
- StatusHistory
- OBS API
- Owner Search
- Search
- Links
- Distributions
- Distribution Support
- Repository
- Data Migrations
- Package Versions
- Rails Update
- Ruby Update
- Updating-rake-or-rack
- Brakeman
- Run OpenQA smoketest locally
- Factory Dashboard
- Responsive Guidelines
- osc
- Importing database dumps
- Problem Statement & Solution
- Kickoff New Stuff
- Mob-Programming Sessions
- New Swagger API doc
- Documentation and Communication
- GitHub Actions
- Setup an OBS Development Environment on macOS
- Remote Pairing Setup Guide
- How to Introduce Software Design Patterns
- Query Objects
- Services
- View Components
- RFC: Core Components
- RFC: Decorator Pattern
- RFC: Backend models
- RFC: Hotwire Turbo Frames Pattern