or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing
xxxxxxxxxx
New Python bootstrap in Fedora
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →What is covered by this guide?
Initial bootstrap
Don't panic.
Process gist: Start with Fedora Change. Prepare the Fedora copy of Python and create the first Python builds. Use Koji to run Python scratch builds (the builds last long and Koji has got all the architectures). Once having a working build, start with Copr and move the Fedora dist-git component in parallel. There may be different issues happening only in Copr or Koji, that's alright.
Fedora Change
ChangeReadyForWrangler
only after the previous step is doneUpdate Fedora-Python git repository with new Python
We maintain our git copy of Python, including the downstream-only patches which have to be rebased on top of the upstream code.
Repeat for every new Python release. See Fedora Python interpreter maintenance guide for the details of Python interpreter maintenance.
git pull origin
git log vXXX
(e.g.v3.13.0a1
)fedora
in my local copy – referred as such later onfedora
repository:git fetch fedora
git checkout fedora-X.Y
(e.g.fedora-3.12
)git checkout -b fedora-X.Y
(e.g.fedora-3.13
)git rebase --interactive vXXX
(e.g.v3.13.0a1
) – you'll see a lot of commits relevant to the after-branch phase of the previous release, remove them and leave only the Fedora's patchesgit push fedora fedora-X.Y
(e.g.fedora-3.13
)git tag fedora-3.13.0a1-1
git push fedora fedora-3.13.0a1-1
In case something went wrong, don't worry. Force pushing is allowed and in fact desired.
Add the new Python component to the Fedora dist-git
We ship the new Python as a non-main Python in all Fedoras immediately. Even the one that'll be EOL soon. It's handy. Folks can use it to test their projects, e.g. using
tox
.Process gist: We import the whole latest state of the Python n-1 to the distgit repository. Then we disable the possibility for direct pushes to the repository. The initial review for the new Python component takes place in Pull Requests. Only after merge the component is actually the new Python version.
fedpkg request-repo pythonX.Y --exception --no-initial-commit
tests/*
!fedpkg new-sources
on the old component)--without tests --without optimizations
git push <remote_name> rawhide
fedpkg request-branch fxx
for each branch,git merge rawhide
,git push --no-verify
(--no-verify
because git will complain about the sources)fedpkg new-sources
the new sources + bring all your stashed changes to the new repositoryOnce shipped, you should open follow-up PRs to disable the bootstrap bcond.
New Python Copr
In parallel, the new Python Copr is created. It mocks an environment where the new Python is a main Python, so the packages actually build using it. We use Fedora Rawhide as the destination system, even though the actual switch to the new main Python will happen in Fedora Rawhide+1.
config.toml
- it contains the bootstrap packages with their bconds to switch and build manually@python
group in Copr (@python-packagers-sig
in FAS).python-rpm-macros
, optioncustom build
with script (replace theN
in the script with the actual major version number)fedpkg
as dependencypython-rpm-macros
This will ensure that generators are built with the new Python (3.N) as the main version - the basics for the rest of the builds
Python n-1
,Python n
and verify:Python n-1
MUST contain versioned artifacts: e.g.python3.12-devel
, it MUST NOT containpython3-devel
Python n
MUST contain the main artifacts:python3-devel
etc.gdb
without Pythonconfig.toml
config.toml
: you want to get metadata from Koji Rawhide and build in Copr, this will change again after the switch of the main Python in Koji (see older commit for inspiration)Rinse and repeat: build all the Python packages
Once the main dependencies are built successfully, it's time to start running builds in Copr.
whatdoibuild
contains two scripts important for now:jobs.py
:python -u jobs.py > progress.pkgs
progress.pkgs
filebconds.py
python bconds.py
config.toml
with bconds, it'll switch them on/off, build the variants and get the metadata about the requirements. It takes a long time. Often we can build a package without tests/docs way before the full version can be built.jobs.py
-progress.pkgs
fileit contains a sorted list of components that the automation figured out as ready for rebuild (= all of their dependencies are already available)
we want to build them in bulk in Copr, it looks differenty for the bconded components and the full ones
once a component appears in the list, it means it's ready for rebuild.
jobs.py
run - it was rebuilt successfully, that's the happy path scenarioprogress.pkgs
, it means it failed to build. We need to investigate. Once in a while we submit builds for the wholeprogress.pkgs
contents, it sometimes solves transient issues(only first time) Set
COPR=@python/python3.N
and send it to Copr with:commit
progress.pkgs
to git each time after submitting packages to Copr to be able to see the updated diff after eachjobs.py
run(regular updates): run
jobs.py
and explore if there's anything new to build withgit diff progress.pkgs | grep -E '^\+[^+]' | sed 's/^+//'
; if yes, then:Next steps - recurring during the whole bootstrap year
Unblocking the possibility to build new packages
jobs.py
outputs:last-blocking means that when this component builds, it will directly unblock the given amount of packages. To determine what the package needs (and has not been built yet) use
jobs.py
with the package name as the argument:It can take more arguments, as you go down the dependency tree. Find the packages that were not built successfully, even though their dependencies are ready - these need to be repaired.
They need to be broken, typically by bconds. Examine package in dist-git. If there's an applicable bcond, add it to
config.toml
. If there isn't, investigate the ways to break the loop (typically by conditionalizing the test run or docs build), commit and submit a PR to the package with an explanation why you do it. Once merged, add it toconfig.toml
. Every timeconfig.toml
is updated, runpython bconds.py
to run the new builds and update the cached data.Note that packages listed in
config.toml
are excluded from dependency loop detection (the detection assumes you broke the loop). But packages evolve over time and the bconds listed in configuration might no longer actually help. The list needs to be maintained.When done, new packages from
jobs.py
may emerge.Reporting the failures
Start as soon as possible to get community involved in reporting and fixing upstream/downstream. It's impossible for us to fix everything, so that's crucial. Some reports will be moot, wrong component, issue not related to the new Python - it's normal and expected.
There's a script for that, monitor_check.py
In the beginning there will likely be hundreds of failures with repeating patterns. Take one and add it to the reasons dict in the script.
Then run the script:
python monitor_check.py --open-bug-reports --with-reason
This will only open the bugs for packages with matches in the reasons dict. When you build the starting few reasons and get rid of the repeating patterns, it's time to report the rest. Drop the
--with-reason
option to open bugz for all the failures.Important components that block a lot of packages will use our heavy lifting. Report upstream, ask the team experts on CPython (@vstinner) for help, submit PRs that are in your capacity.
Knowledge base on issues we encounter
cmake
Heaven knows why we have to add new Python to cmake every year: example. Many projects bundle cmake scripts, so expect to patch ~10 of others just to make them see Python 3.N as a valid interpreter.
The latest commits in distgit cause package to FTBFS
The background: In Fedora distgit there are commits to a component that cause FTBFS. The last build in Koji failed (or the changes were never attempted to build). Our script gets the data from Koji, i.e. from the latest successful build. Then, once it figures out the dependencies, we build the state that's present in Fedora distgit - which is broken. Koschei will not notify us about such situations, because it rebuilds from the latest SRPMs rather than from distgit.
The solution: None known. When inspecting weird build failures, always take a look at the list of the latest commits in distgit of a component. Look at the build information associated with each commit (it's displayed as a number next to the commit hash in Pagure): there will be none or it will be written in red-coloured font. Explore the logs, if available, to check if the failure is similar. Open a generic FTBFS bugzilla.
Dirty hacks
The background: The package FTBFS in Copr. We decide to do some modifications to the spec (e.g. disable tests, remove some dependencies) and fire a build in Copr with such local change. The change is too hacky to add to the real component or we deliberately keep it only local for a moment. Then the actual mass rebuild happens and everything falls apart, because we forgot
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →The solution: We keep a document containing such changes: https://hackmd.io/@befeleme/shorime-za-to-v-pekle and regularly review the issues there.
Critpaths testing
When mass-rebuild is approaching and your Copr is in a quite good shape, it's beneficial to test the critical paths components and the python-classroom one. We don't want to start a mass rebuild and render an uninstallable Fedora by accident. A typical issue arises with anaconda, which doesn't run any tests during the build and hence is often uninstallable.
Critical path components are stored in fedora-comps repository, the list is maintained in a relevant file, e.g. comps-f43.xml.in. Clone the repository to work with it locally. Grab all the paths from the file:
grep -F '>critical-path' comps-fNN.xml.in
Initialize empty mock with your copr config, ensure the Python version is the new one and try to install a critical path one after another, e.g.:
Review the transaction errors to unblock the components on time.
Mass rebuild in Koji
TODO:
Side-tag requests
E-mail announcements
When you're about to start the mass-rebuild, make sure you communicate with the Fedora community. Send the comms to
devel-announce@lists.fedoraproject.org
,devel@lists.fedoraproject.org
,python-devel@lists.fedoraproject.org
It'll likely be a few e-mails in total:
Preparing mass-rebuild
When the side tag is ready to build in it, we need to bootstrap Python and the basic components again there, very similar way we did it in Copr.
distgit changes for the real rebuild
_fedpkg_cache_dir
%global _with{out}_<bcond_name>
to the first line of the specfilegit diff > ../../patches_dir/<component_name>.patch
patches_dir
Changes to config.toml https://github.com/hroncok/whatdoibuild/commit/78c670e0299397c04b12c6e0ec0ccd71f8f5c396,
try it in a dry mode first
clean progress.pkgs
when ready, comment out the exception raising (https://github.com/hroncok/whatdoibuild/commit/e24e03418c58a211bde50ea090f6f7556a72751a)
Mass-rebuild
Use jobs.py as with copr to generate the list of ready-to-build package names in progress.pkgs. Build them with
build.py
. When properly configured, it will:_fedpkg_cache_dir
Run as
python build.py <pkgname>
or with parallel and multiple pkgnames:parallel python build.py -- $(git diff progress.pkgs | grep -E '^\+[^+]' | sed 's/^+//') > log
Obsoleting not working packages
Some packages will never successfully build with the new Python. If people have them installed on their machines, they would remain there forever, although they'd be unusable, as they would require python(abi) of Python X.Y-1. To avoid not working packages lingering on the people's machines, we can employ a special package - fedora-obsolete-packages. It will remove the defined packages from the user machine on a system update.
Fedora supports upgrades up to two versions at once. For the odd Fedora version, when we change the main Python version, it should happen in both the Beta Freeze and Final Freeze phases. And then again, for the even Fedora version, which still supports upgrades from one Fedora version with the obsolete main Python, it should happen in a Final Freeze phase. See table for illustration:
We've got to find packages existing in the supported upgrade path versions which still require python(abi) = 3.Y-1. Use a script doing exactly that and paste its output to
fedora-obsolete-packages.spec
, the Python packages section.For the first PR for a given main Python version, prepare one commit removing the old contents, and add a new commit with a list of new obsolete packages. For inspiration see Fedora 41 first PR.
For the even Fedora version, generate the list of obsoleted packages, but work with the resulting diff, so that packages are only included to the list, not removed. See Fedora 42 obsolete update.
Because we do it in the Freeze phase, we need a Freeze Exception for this exercise. Create an obsolete packages bugzilla and set it to block the desired target:
BetaFreezeException
orFinalFreezeException
. Reuse that bug for both releases containing the same Python version. Block the main Python tracker too.To remember about the important dates, subscribe to fedora-release-schedule-ical which is a cleaned-up official Fedora calendar.