1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
|
.. _basic workflow dev guide:
Basic Workflow
==============
The following chart illustrates the basic Ceph development workflow:
.. ditaa::
Upstream Code Your Local Environment
/----------\ git clone /-------------\
| Ceph | -------------------------> | ceph/main |
\----------/ \-------------/
^ |
| | git branch fix_1
| git merge |
| v
/----------------\ git commit --amend /-------------\
| ninja check |---------------------> | ceph/fix_1 |
| ceph--qa--suite| \-------------/
\----------------/ |
^ | fix changes
| | test changes
| review | git commit
| |
| v
/--------------\ /-------------\
| github |<---------------------- | ceph/fix_1 |
| pull request | git push \-------------/
\--------------/
This page assumes that you are a new contributor with an idea for a bugfix or
an enhancement, but you do not know how to proceed. Watch the `Getting Started
with Ceph Development <https://www.youtube.com/watch?v=t5UIehZ1oLs>`_ video (1
hour 15 minutes) for a practical summary of this workflow.
Updating the tracker
--------------------
Find the :ref:`issue-tracker` (Redmine) number of the bug you intend to fix. If
no tracker issue exists, create one. There is only one case in which you do not
have to create a Redmine tracker issue: the case of minor documentation changes.
Simple documentation cleanup does not require a corresponding tracker issue.
Major documentation changes do require a tracker issue. Major documentation
changes include adding new documentation chapters or files, and making
substantial changes to the structure or content of the documentation.
A (Redmine) tracker ticket explains the issue (bug) to other Ceph developers to
keep them informed as the bug nears resolution. Provide a useful, clear title
and include detailed information in the description. When composing the title
of the ticket, ask yourself "If I need to search for this ticket two years from
now, which keywords am I likely to search for?" Then include those keywords in
the title.
If your tracker permissions are elevated, assign the bug to yourself by setting
the ``Assignee`` field. If your tracker permissions have not been elevated,
just add a comment with a short message that says "I am working on this issue".
Ceph Workflow Overview
----------------------
Three repositories are involved in the Ceph workflow. They are:
1. The upstream repository (``ceph/ceph``)
2. Your fork of the upstream repository (``your_github_id/ceph``)
3. Your local working copy of the repository (on your workstation)
The procedure for making changes to the Ceph repository is as follows:
#. Configure your local environment
#. :ref:`Create a fork<forking>` of the "upstream Ceph"
repository.
#. :ref:`Clone the fork<cloning>` to your local filesystem.
#. Fix the bug
#. :ref:`Synchronize local main with upstream main<synchronizing>`.
#. :ref:`Create a bugfix branch<bugfix_branch>` in your local working copy.
#. :ref:`Make alterations to the local working copy of the repository in your
local filesystem<fixing_bug_locally>`.
#. :ref:`Push the changes in your local working copy to your fork<push_changes>`.
#. Create a Pull Request to push the change upstream.
#. Create a Pull Request that asks for your changes to be added into the
"upstream Ceph" repository.
Preparing Your Local Working Copy of the Ceph Repository
--------------------------------------------------------
The procedures in this section, "Preparing Your Local Working Copy of the Ceph
Repository", must be followed only when you are first setting up your local
environment. If this is your first time working with the Ceph project, then
these commands are necessary and are the first commands that you should run.
.. _forking:
Creating a Fork of the Ceph Repository
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
See the `GitHub documentation
<https://help.github.com/articles/fork-a-repo/#platform-linux>`_ for
detailed instructions on forking. In short, if your GitHub username is
"mygithubaccount", your fork of the upstream repo will appear at
``https://github.com/mygithubaccount/ceph``.
.. _cloning:
Cloning Your Fork
^^^^^^^^^^^^^^^^^
After you have created your fork, clone it by running the following command:
.. prompt:: bash $
git clone https://github.com/mygithubaccount/ceph
You must fork the Ceph repository before you clone it. If you fail to fork,
you cannot open a `GitHub pull request
<https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request>`_.
For more information on using GitHub, refer to `GitHub Help
<https://help.github.com/>`_.
Configuring Your Local Environment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The commands in this section configure your local git environment so that it
generates ``Signed-off-by:`` tags. These commands also set up your local
environment so that it can stay synchronized with the upstream repository.
The commands in this section are necessary only during the initial setup of
your local working copy. This means that these commands are necessary only the
first time that you are working with the Ceph repository. They are, however,
unavoidable, and if you fail to run them then you will not be able to work on
the Ceph repository..
1. Configure your local git environment with your name and email address.
.. note::
These commands will work only from within the ``ceph/`` directory
that was created when you cloned your fork.
.. prompt:: bash $
git config user.name "FIRST_NAME LAST_NAME"
git config user.email "MY_NAME@example.com"
2. Add the upstream repo as a "remote" and fetch it:
.. prompt:: bash $
git remote add ceph https://github.com/ceph/ceph.git
git fetch ceph
These commands fetch all the branches and commits from ``ceph/ceph.git`` to
the local git repo as ``remotes/ceph/$BRANCH_NAME`` and can be referenced as
``ceph/$BRANCH_NAME`` in local git commands.
Fixing the Bug
--------------
.. _synchronizing:
Synchronizing Local Main with Upstream Main
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In your local working copy, there is a copy of the ``main`` branch in
``remotes/origin/main``. This is called "local main". This copy of the
main branch (https://github.com/your_github_id/ceph.git) is "frozen in time"
at the moment that you cloned it, but the upstream repo
(https://github.com/ceph/ceph.git, typically abbreviated to ``ceph/ceph.git``)
that it was forked from is not frozen in time: the upstream repo is still being
updated by other contributors.
Because upstream main is continually receiving updates from other contributors,
over time your fork will drift farther and farther from the state of the
upstream repository as it was when you cloned it.
Keep your fork's ``main`` branch synchronized with upstream main to reduce
drift between your fork's main branch and the upstream main branch.
Here are the commands for keeping your fork synchronized with the
upstream repository:
.. prompt:: bash $
git fetch ceph
git checkout main
git reset --hard ceph/main
git push -u origin main
Follow this procedure often to keep your local ``main`` in sync with upstream
``main``.
If the command ``git status`` returns a line that reads "Untracked files", see
:ref:`the procedure on updating submodules <update-submodules>`.
.. _bugfix_branch:
Creating a Bugfix branch
^^^^^^^^^^^^^^^^^^^^^^^^
Create a branch for your bugfix:
.. prompt:: bash $
git checkout main
git checkout -b fix_1
git push -u origin fix_1
The first command (``git checkout main``) makes sure that the bugfix branch
"fix_1" is created from the most recent state of the main branch of the
upstream repository.
The second command (``git checkout -b fix_1``) creates a "bugfix branch" called
"fix_1" in your local working copy of the repository. The changes that you make
in order to fix the bug will be committed to this branch.
The third command (``git push -u origin fix_1``) pushes the bugfix branch from
your local working repository to your fork of the upstream repository.
.. _fixing_bug_locally:
Fixing the bug in the local working copy
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#. **Updating the tracker**
In the `Ceph issue tracker <https://tracker.ceph.com>`_, change the status
of the tracker issue to "In progress". This communicates to other Ceph
contributors that you have begun working on a fix, which helps to avoid
duplication of effort. If you don't have permission to change that field,
just comment that you are working on the issue.
#. **Fixing the bug itself**
This guide cannot tell you how to fix the bug that you have chosen to fix.
This guide assumes that you have identified an area that required
improvement, and that you know how to make that improvement.
It might be that your fix is simple and that it requires only minimal
testing. But that's unlikely unless you're updating only documentation. It
is more likely that the process of fixing your bug will require several
rounds of testing. The testing process is likely to be iterative and will
involve trial, error, skill, and patience.
For a detailed discussion of the tools available for validating bugfixes,
see :ref:`the sections that discuss testing <dev-testing-unit-tests>`.
Pushing the Fix to Your Fork
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You have finished work on the bugfix. You have tested the bugfix, and you
believe that it works.
#. Commit the changes to your local working copy.
Commit the changes to the ``fix_1`` branch of your local working copy by
using the ``--signoff`` option (here represented as the ``s`` portion of the
``-as`` flag):
.. prompt:: bash $
git commit -as
.. _push_changes:
#. Push the changes to your fork:
Push the changes from the ``fix_1`` branch of your local working copy to the
``fix_1`` branch of your fork of the upstream repository:
.. prompt:: bash $
git push origin fix_1
.. note::
In the command ``git push origin fix_1``, ``origin`` is the name of your
fork of the upstream Ceph repository, and can be thought of as a nickname
for ``git@github.com:username/ceph.git``, where ``username`` is your
GitHub username.
It is possible that ``origin`` is not the name of your fork. Discover the
name of your fork by running ``git remote -v``, as shown here:
.. code-block:: bash
$ git remote -v
ceph https://github.com/ceph/ceph.git (fetch)
ceph https://github.com/ceph/ceph.git (push)
origin git@github.com:username/ceph.git (fetch)
origin git@github.com:username/ceph.git (push)
The line::
origin git@github.com:username/ceph.git (fetch)
and the line::
origin git@github.com:username/ceph.git (push)
provide the information that ``origin`` is the name of your fork of the
Ceph repository.
Opening a GitHub pull request
-----------------------------
After you have pushed the bugfix to your fork, open a GitHub pull request
(PR). This makes your bugfix visible to the community of Ceph contributors.
They will review it. They may perform additional testing on your bugfix, and
they might request changes to the bugfix.
Be prepared to receive suggestions and constructive criticism in the form of
comments within the PR.
If you don't know how to create and manage pull requests, read `this GitHub
pull request tutorial`_.
.. _`this GitHub pull request tutorial`:
https://help.github.com/articles/using-pull-requests/
To learn what constitutes a "good" pull request, see
the `Git Commit Good Practice`_ article at the `OpenStack Project Wiki`_.
.. _`Git Commit Good Practice`: https://wiki.openstack.org/wiki/GitCommitMessages
.. _`OpenStack Project Wiki`: https://wiki.openstack.org/wiki/Main_Page
See also Ceph's own `Submitting Patches
<https://github.com/ceph/ceph/blob/main/SubmittingPatches.rst>`_ document.
After your pull request (PR) has been opened, update the :ref:`issue-tracker`
by adding a comment directing other contributors to your PR. The comment can be
as simple as this::
*PR*: https://github.com/ceph/ceph/pull/$NUMBER_OF_YOUR_PULL_REQUEST
Understanding Automated PR validation
-------------------------------------
When you create or update your PR, the Ceph project's `Continuous Integration
(CI) <https://en.wikipedia.org/wiki/Continuous_integration>`_ infrastructure
automatically tests it. Here are just some of the automated tests that are
performed on your PR:
#. a test to check that the commits are properly signed (see
:ref:`submitting-patches`):
#. a test to check that the documentation builds
#. a test to check that the submodules are unmodified
#. a test to check that the API is in order
#. a :ref:`make check<make-check>` test
Additional tests may be run, depending which files your PR modifies.
The :ref:`make check<make-check>` test builds the PR and runs it through a
battery of tests. These tests run on servers that are operated by the Ceph
Continuous Integration (CI) team. When the tests have completed their run, the
result is shown on GitHub in the pull request itself.
Test your modifications before you open a PR. Refer to :ref:`the sections on
testing <dev-testing-unit-tests>` for details.
Notes on PR make check test
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The GitHub :ref:`make check<make-check>` test is driven by a Jenkins instance.
Jenkins merges your PR branch into the latest version of the base branch before
it starts any tests. This means that you don't have to rebase the PR in order
to pick up any fixes.
You can trigger PR tests at any time by adding a comment to the PR - the
comment should contain the string "test this please". Since a human who is
subscribed to the PR might interpret that as a request for him or her to test
the PR, you must address Jenkins directly. For example, write "jenkins retest
this please". If you need to run only one of the tests, you can request it with
a command like "jenkins test signed". A list of these requests is automatically
added to the end of each new PR's description, so check there to find the
single test you need.
If there is a build failure and you aren't sure what caused it, check the
:ref:`make check<make-check>` log. To access the make check log, click the
"details" (next to the :ref:`make check<make-check>` test in the PR) link to
enter the Jenkins web GUI. Then click "Console Output" (on the left).
Jenkins is configured to search logs for strings that are known to have been
associated with :ref:`make check<make-check>` failures in the past. However,
there is no guarantee that these known strings are associated with any given
:ref:`make check<make-check>` failure. You'll have to read through the log to
determine the cause of your specific failure.
Integration tests AKA ceph-qa-suite
-----------------------------------
It may be necessary to test your fix on real Ceph clusters that run on physical
or virtual hardware. Tests designed for this purpose reside in the `ceph/qa
sub-directory`_ and are run via the `teuthology framework`_.
.. _`ceph/qa sub-directory`: https://github.com/ceph/ceph/tree/main/qa/
.. _`teuthology repository`: https://github.com/ceph/teuthology
.. _`teuthology framework`: https://github.com/ceph/teuthology
The Ceph community has access to the `Sepia lab
<https://wiki.sepia.ceph.com/doku.php>`_ where `integration tests`_ can be run
on physical hardware.
Other contributors might add tags like ``needs-qa`` to your PR. This allows PRs
to be merged into a single branch and then efficiently tested together.
Teuthology test suites can take hours (and, in some cases, days) to
complete, so batching tests reduces contention for resources and saves
time.
If your code change has any effect on upgrades, add the
``needs-upgrade-testing`` label. This indicates that an upgrade testing suite
should be scheduled.
To request access to the Sepia lab, start `here
<https://wiki.sepia.ceph.com/doku.php?id=vpnaccess>`_.
Integration testing is discussed in more detail in the `integration
tests`_ chapter.
.. _integration tests: ../testing_integration_tests/tests-integration-testing-teuthology-intro
Code review
-----------
After your bugfix has been thoroughly tested--and sometimeseven during the
testing--it will be subjected to code review by other developers. This
typically takes the form of comments in the PR itself, but can be supplemented
by discussions on :ref:`irc`, or on :ref:`Slack <ceph-slack>` or on the
:ref:`mailing-list`.
Amending your PR
----------------
While your PR is going through testing and `Code Review`_, you can
modify it at any time by editing files in your local branch.
After updates are committed locally (to the ``fix_1`` branch in our
example), they must be pushed to GitHub in order to appear in the PR.
Modifying the PR is done by adding commits to the ``fix_1`` branch upon which
it is based, often followed by rebasing to modify the branch's git history. See
`this tutorial <https://www.atlassian.com/git/tutorials/rewriting-history>`_
for an introduction to rebasing. When you are done with your modifications, you
will need to force push your branch by running a command of the following form:
.. prompt:: bash $
git push --force origin fix_1
Why do we take these extra steps instead of simply adding additional commits to
the PR? It is best practice for a PR to consist of a single commit; this makes
it possible to maintain a clean history, it simplifies peer review of your
changes, and it makes merging your PR easier. In the unlikely event that your
PR has to be reverted, having a single commit associated with that PR makes the
procession of reversion easier.
Merging
-------
The bugfix process completes when a project lead merges your PR.
When this happens, it is a signal for you (or the lead who merged the PR)
to change the :ref:`issue-tracker` status to "Resolved". Some issues may be
flagged for backporting, in which case the status should be changed to
"Pending Backport" (see the :ref:`backporting` chapter for details).
See :ref:`merging` for more information on merging.
Proper Merge Commit Format
^^^^^^^^^^^^^^^^^^^^^^^^^^
This is the most basic form of a merge commit::
doc/component: title of the commit
Reviewed-by: Reviewer Name <rname@example.com>
This consists of two parts:
#. The title of the commit to be merged.
#. The name and email address of the reviewer. Enclose the reviewer's email
address in angle brackets.
Using a browser extension to auto-fill the merge message
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you use a browser to merge GitHub PRs, the easiest way to fill in
the merge message is with the `"Ceph GitHub Helper Extension"
<https://github.com/tspmelo/ceph-github-helper>`_ (available for `Chrome
<https://chrome.google.com/webstore/detail/ceph-github-helper/ikpfebikkeabmdnccbimlomheocpgkmn>`_
and `Firefox <https://addons.mozilla.org/en-US/firefox/addon/ceph-github-helper/>`_).
After enabling this extension, if you go to a GitHub PR page, a vertical helper
will be displayed at the top-right corner. If you click on the user silhouette
button the merge message input will be automatically populated.
Using .githubmap to Find a Reviewer's Email Address
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you cannot find the email address of the reviewer on his or her GitHub page,
you can look it up in the ``.githubmap`` file, which can be found in the
repository at ``/ceph/.githubmap``.
Using "git log" to find a Reviewer's Email Address
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you cannot find a reviewer's email address by using the above methods, you
can search the git log for their email address. Reviewers are likely to have
committed something before. If they have made previous contributions, the git
log will probably contain their email address.
Use the following command:
.. prompt:: bash [branch-under-review]$
git log
Using ptl-tool to Generate Merge Commits
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Another method of generating merge commits involves using Patrick Donnelly's
``ptl-tool`` to pull commits. This tool can be found at
``/ceph/src/script/ptl-tool.py``. Merge commits that have been generated by the
``ptl-tool`` have the following form::
Merge PR #36257 into main
* refs/pull/36257/head:
client: move client_lock to _unmount()
client: add timer_lock support
Reviewed-by: Patrick Donnelly <pdonnell@redhat.com>
Miscellaneous
-------------
--set-upstream
^^^^^^^^^^^^^^
If you forget to include the ``--set-upstream origin x`` option in your ``git
push`` command, you will see the following error message:
::
fatal: The current branch {x} has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin {x}
To set up git to automatically create the upstream branch that corresponds to
the branch in your local working copy (without having to add the option
``--set-upstream origin x`` every time), run this command from within the
``ceph/`` directory:
.. prompt:: bash $
git config --global push.autoSetupRemote true
Deleting a Branch Locally
^^^^^^^^^^^^^^^^^^^^^^^^^
To delete the branch named ``localBranchName`` from the local working copy, run
a command of this form:
.. prompt:: bash $
git branch -d localBranchName
Deleting a Branch Remotely
^^^^^^^^^^^^^^^^^^^^^^^^^^
To delete the branch named ``remoteBranchName`` from the remote upstream branch
(which is also your fork of ``ceph/ceph``, as described in :ref:`forking`), run
a command of the following form:
.. prompt:: bash $
git push origin --delete remoteBranchName
Searching a File Longitudinally for a String
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To search for the commit that introduced a given string (in this example, that
string is ``foo``) into a given file (in this example, that file is
``file.rst``), use the ``-S <string>`` option. Run a command of the following
form:
.. prompt:: bash $
git log -S 'foo' file.rst
|