Basic Workflow
The following chart illustrates the basic Ceph development workflow:
The below explanation is written with the assumption that you, the reader, are a new contributor who has an idea for a bugfix or enhancement, but do not know exactly how to proceed. Watch the Getting Started with Ceph Development video for a practical summary of this workflow.
Update the tracker
Before you start, you should know the Issue Tracker (Redmine) number of the bug you intend to fix. If there is no tracker issue, now is the time to create one for code changes. Straightforward documentation cleanup does not necessarily require a corresponding tracker issue. However, an issue (ticket) should be created if one is adding new documentation chapters or files, or for other substantial changes.
The tracker ticket serves to explain the issue (bug) to your fellow Ceph developers and keep them informed as you make progress toward resolution. To this end, please provide a descriptive title and write appropriate information and details into the description. When composing the ticket’s title, consider “If I want to search for this ticket two years from now, what keywords will I search for?”
If you have sufficient tracker permissions, assign the bug to yourself by setting the Assignee
field. If your tracker permissions have not been elevated, simply add a comment with a short message like “I am working on this issue”.
Upstream code
This section, and the ones that follow, correspond to nodes in the above chart.
The upstream code is found at https://github.com/ceph/ceph.git, which is known as the “upstream repo”, or simply “upstream”. As the chart shows, we will make a local copy of this repository, modify it, test our modifications, then submit the modifications for review and merging.
A local copy of the upstream code is made by
Forking the upstream repo on GitHub, and
Cloning your fork to make a local working copy
See the GitHub documentation 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. Once you have created your fork, clone it by running:
git clone https://github.com/mygithubaccount/ceph
While it is possible to clone the upstream repo directly, for the Ceph workflow you must fork it first. Forking is what enables us to open a GitHub pull request.
For more information on using GitHub, refer to GitHub Help.
Local environment
In the local environment created in the previous step, you now have a copy of the master
branch in remotes/origin/master
. This fork (https://github.com/mygithubaccount/ceph.git) is frozen in time and the upstream repo (https://github.com/ceph/ceph.git, typically abbreviated to ceph/ceph.git
) is updated frequently by other contributors, you must sync your fork periodically. Failure to do so may result in your commits and pull requests failing to merge because they refer to file contents that have since changed.
First, ensure that you have properly configured your local git environment with your name and email address. Skip this step if you have already configured this information.
git config user.name "FIRST_NAME LAST_NAME"
git config user.email "MY_NAME@example.com"
Now add the upstream repo as a “remote” and fetch it:
git remote add ceph https://github.com/ceph/ceph.git
git fetch ceph
Fetching downloads all objects (commits, branches) that were added since the last sync. After running these commands, all the branches from ceph/ceph.git
are downloaded to the local git repo as remotes/ceph/$BRANCH_NAME
and can be referenced as ceph/$BRANCH_NAME
in local git commands.
For example, your local master
branch can be reset to the upstream Ceph master
branch by running
git fetch ceph
git checkout master
git reset --hard ceph/master
Finally, the master
branch of your fork is synced to the upstream master by
git push -u origin master
Bugfix branch
Next, create a branch for your bugfix:
git checkout master
git checkout -b fix_1
git push -u origin fix_1
This creates a fix_1
branch locally and in our GitHub fork. At this point, the fix_1
branch is identical to the master
branch, but not for long! You are now ready to modify the code. Be careful to always run git checkout master first, otherwise you may find commits from an unrelated branch mixed with your new work.
Fix bug locally
Now change the status of the tracker issue to “In progress” to communicate to other Ceph contributors that you have begun working on a fix. This helps avoid duplication of effort. If you don’t have permission to change that field, your previous comment that you are working on the issue is sufficient.
Your fix may be very simple and require only minimal testing. More likely, this will be an iterative process involving trial and error, not to mention skill. An explanation of how to fix bugs is beyond the scope of this document. Instead, we focus on the mechanics of the process in the context of the Ceph project.
For a detailed discussion of the tools available for validating bugfixes, see the chapters on testing.
For now, let us just assume that you have finished work on the bugfix, that you have tested, and that you believe it works. Commit the changes to your local branch using the --signoff
option
git commit -as
and push the changes to your fork
git push origin fix_1
GitHub pull request
The next step is to open a GitHub pull request (PR). This makes your bugfix visible to the community of Ceph contributors. They will review it and may perform additional testing and / or request changes.
This is the point where you “go public” with your modifications. Be prepared to receive suggestions and constructive criticism in the form of comments within the PR. Don’t worry! The Ceph project is a friendly place!
If you are uncertain how to create and manage pull requests, you may read this GitHub pull request tutorial.
For ideas on what constitutes a “good” pull request, see the Git Commit Good Practice article at the OpenStack Project Wiki.
and our own Submitting Patches document.
Once your pull request (PR) is opened, update the Issue Tracker by adding a comment directing other contributors to your PR. The comment can be as simple as:
*PR*: https://github.com/ceph/ceph/pull/$NUMBER_OF_YOUR_PULL_REQUEST
Automated PR validation
When your PR is created or updated, the Ceph project’s Continuous Integration (CI) infrastructure will test it automatically. At the time of this writing (September 2020), the automated CI testing included five tests to check that the commits in the PR are properly signed (see Submitting patches), to check that the documentation builds, to check that the submodules are unmodified, to check that the API is in order, and a What does “make check” mean? test. Additional tests may be performed depending on which files are modified by your PR.
The What does “make check” mean?, builds the PR and runs it through a battery of tests. These tests run on servers operated by the Ceph Continuous Integration (CI) team. When the tests complete, the result will be shown on GitHub in the pull request itself.
You can (and should) also test your modifications before you open a PR. Refer to the chapters on testing for details.
Notes on PR make check test
The GitHub make check test is driven by a Jenkins instance.
Jenkins merges your PR branch into the latest version of the base branch before starting tests. This means that you don’t have to rebase the PR 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 subscribed to the PR might interpret that as a request for him or her to test the PR, we recommend that you address Jenkins directly. For example, write “jenkins retest this please”. For efficiency a single re-test can also be requested with e.g. “jenkins test signed”. For reference, a list of these requests is automatically added to the end of each new PR’s description.
If there is a build failure and you aren’t sure what caused it, check the make check log. To access it, click on the “details” (next to the make check test in the PR) link to enter the Jenkins web GUI. Then click on “Console Output” (on the left).
Jenkins is configured to search logs for strings known to have been associated with make check failures in the past. However, there is no guarantee that these known strings are associated with any given 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
Since Ceph is complex, it may be necessary to test your fix to see how it behaves on real clusters running on physical or virtual hardware. Tests designed for this purpose live in the ceph/qa sub-directory and are run via the teuthology framework.
The Ceph community has access to the Sepia lab where Testing - Integration Tests can be run on physical hardware. Other developers may add tags like “needs-qa” to your PR. This allows PRs that need testing to be merged into a single branch and tested all at the same time. Since teuthology suites can take hours (even days in some cases) to run, this can save a lot of time.
To request access to the Sepia lab, start here.
Integration testing is discussed in more detail in the Testing - Integration Tests chapter.
Code review
Once your bugfix has been thoroughly tested, or even during this process, 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 IRC and the Mailing lists.
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 need to be pushed to GitHub so they 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 for a good introduction to rebasing. When you are done with your modifications, you will need to force push your branch with:
git push --force origin fix_1
Why do we take these extra steps instead of simply adding additional commits the the PR? It is best practice for a PR to consist of a single commit; this makes for clean history, eases peer review of your changes, and facilitates merges. In rare circumstances it also makes it easier to cleanly revert changes.
Merge
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 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 Backporting chapter for details).
See also Commit merging: scope and cadence 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 / PR to be merged.
The name and email address of the reviewer. Enclose the reviewer’s email address in angle brackets.
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
git log
Using ptl-tool to Generate Merge Commits
Another method of generating merge commits involves using Patrick Donnelly’s ptl-tool 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 master
* refs/pull/36257/head:
client: move client_lock to _unmount()
client: add timer_lock support
Reviewed-by: Patrick Donnelly <pdonnell@redhat.com>