Project

General

Profile

HOWTO backport commits » History » Version 50

Nathan Cutler, 09/18/2019 10:43 AM

1 24 Loïc Dachary
h3. Backport commits
2 1 Loïc Dachary
3 48 Nathan Cutler
h4. General guidelines
4 37 Nathan Cutler
5
* backports should be done by cherry-picking commits that are in master, and in the most minimal way possible - see [[HOWTO_review_backport_PRs]] for more information
6
* it should be clear which bug the backport is fixing
7
* features can be backported only with permission from the relevant lead
8
* the tracker issue should state why the backport is necessary
9 36 Nathan Cutler
10 48 Nathan Cutler
h4. Detailed instructions:
11 36 Nathan Cutler
12 35 Loïc Dachary
* Pick one entry with the highest *Priority* field in the list of backports linked from [[HOWTO|the top level page]] (for instance "hammer backports":http://tracker.ceph.com/projects/ceph/issues?query_id=78)
13
* Assign the issue to yourself (or add a comment if you do not have permission) so that people know you start working on it.
14 50 Nathan Cutler
* <code>git clone</code> your fork of http://github.com/ceph/ceph (for example, if your GitHub username is "foo", do: <code>git clone https://github.com/foo/ceph.git ; cd ceph</code>
15
* if you already have a clone of your fork, use <code>git remote -v</code> to determine the remote name. In the text that follows, we'll assume the remote name of your fork is <code>origin</code>, but that might not be the case on your system - please check
16 23 Nathan Cutler
* <code>git checkout -b wip-$issue-$release origin/$release</code> to create a branch with a name that reflects the issue being fixed and the target release: this naming is convenient to select all branches containing backports for firefly or select all branches containing backports for a specific issue
17 32 Loïc Dachary
* <code>git cherry-pick -x</code> the commits from the pull request that was targeting <code>master</code> (not from the pull requests targeting stable branches -- with the exception of the upcoming stable branch, which can be used because all commits to the upcoming stable branch are merged into <code>master</code> on a regular basis)
18 19 Loïc Dachary
** the original issue is linked in the *Related issues* section of the issue, as a *Copied from* link
19
** the pull request or commit targeting master can be found by following the *Copied from* link and searching the original issue
20 34 Nathan Cutler
** TIP: if the cherry-pick fails due to whitespace differences, use <code>-Xignore-all-space</code>
21 39 Nathan Cutler
* <code>git push -u origin wip-$issue-$release</code> to publish the branch on github and be able to create a pull request from it
22 44 Nathan Cutler
* Create the pull request, targeting the branch you are backporting to, set milestone as appropriate, prefix the PR title with <code>$release: </code> and put the backport tracker URL in the PR description
23 39 Nathan Cutler
* Edit the backport tracker issue, putting the GitHub PR URL in the description - now the backport tracker and PR are interlinked
24
* Set the backport tracker status to "In Progress", and assign it to yourself
25
26
Do not merge the pull request yet. Merging only takes place after the backports pass [[HOWTO run integration and upgrade tests|integration and upgrade tests]] and with proper approval as described in [[HOWTO merge commits from the integration branch]].
27
28
All commits being backported must be cherry-picked from master. There are exceptions to this rule (see https://github.com/ceph/ceph/pull/4175 for instance: it fixes a regression introduced by an incorrect resolution of a backport) but they are rare. When a backport is done to fix a bug that shows in the integration tests or upgrade tests run by cron, testing the backport in an integration branch is redundant because the existing tests will keep failing.
29
30 48 Nathan Cutler
h4. How to automate
31 39 Nathan Cutler
32 16 Loïc Dachary
* generate a *$github_token* by "following the GitHub instructions":https://help.github.com/articles/creating-an-access-token-for-command-line-use/
33 14 Loïc Dachary
* retrieve the *$redmine_key*: it is a token that will allow you to script issue updates
34
** login http://tracker.ceph.com/
35
** visit http://tracker.ceph.com/my/account
36
** look for *API access key* in the page (Control-f)
37
** click on the *Show* link just under *API access key*
38
** copy the hexadecimal number it shows
39 1 Loïc Dachary
** redmine_key=b586ce6a7a936e71f351c93ac0b65a588d4333
40 40 Nathan Cutler
* retrieve the *$redmine_user_id* - this is an integer, not your username. It can be found by logging in at http://tracker.ceph.com and then hovering the mouse over the Redmine username at the top right of the page - where it says "Logged in as *myusername*" and examining the URL. The URL will be something like http://tracker.ceph.com/users/2544 where 2544 is the *$redmine_user_id* value.
41 41 Nathan Cutler
* grab the "ceph-backport.sh" script from src/script in "master" branch of https://github.com/ceph/ceph.git
42 39 Nathan Cutler
* make a "backport_common.sh" script that sets the redmine_key, redmine_user_id, and github_token variables to the right values and make sure the "source backport_common.sh" command in the script will not fail
43 42 Nathan Cutler
* follow the instructions in the comment block at the top of "ceph-backport.sh"
44 39 Nathan Cutler
45 49 Nathan Cutler
h4. Notes on cherry-picking
46 45 Nathan Cutler
47 47 Nathan Cutler
The "traditional" method is to cherry-pick each commit from the master PR in turn, and resolve conflicts as you go.
48 1 Loïc Dachary
49 47 Nathan Cutler
If there is a conflict, explain how it was resolved in the commit message, below the Conflicts line. For instance:
50
51 1 Loïc Dachary
<pre>
52 47 Nathan Cutler
commit c60da2f3c34e7325c748d2d6e55140a0a30013fd
53
Author: Samuel Just <sjust@redhat.com>
54
Date:   Thu Nov 20 15:15:08 2014 -0800
55
56
    PGLog: include rollback_info_trimmed_to in (read|write)_log
57
    
58
    Fixes: #10157
59
    Backport: firefly, giant
60
    Signed-off-by: Samuel Just <sjust@redhat.com>
61
    (cherry picked from commit 1fe8b846641486cc294fe7e1d2450132c38d2dba)
62
    
63
    Conflicts:
64
    	src/osd/PGLog.cc
65
            in the context coll_t::META_COLL was replaced with META_COLL
66
</pre>
67
68
The difference between the original commit and the one including a conflict resolution can be displayed with
69
70
<pre>
71
commit=c7d0d51cb574594de6f09457c960347b11fc2474 ; picked_from=$(git show --no-patch --pretty=%b $commit  |  perl -ne 'print if(s/.*cherry picked from commit (\w+).*/$1/)') ; diff -u --ignore-matching-lines '^[^+-]' <(git show $picked_from) <(git show $commit)
72
</pre>
73
74
If the conflict is difficult to resolve, seek help from the author of the original commit (see "librbd: deadlock in image refresh":https://github.com/ceph/ceph/pull/4176 for instance) and assign the issue to her/him, or to a [[HOWTO#Leads|lead]]
75
76
It is also possible to cherry-pick all the commits at once. Since github generates branches for every PR, one can use the following trick:
77
78
<pre>
79 10 Loïc Dachary
git fetch <upstream> pull/<prr-num>/head:pr-<prnum>
80
git cherry-pick -x pr-<pr-num>~<num-commits>..pr-<pr-num>
81 29 Loïc Dachary
</pre>
82 1 Loïc Dachary
83 29 Loïc Dachary
Adding following to somewhere bash can find can make things easier
84
85 2 Loïc Dachary
<pre>
86
prfetch() {
87
    git fetch upstream pull/${1}/head:pr-${1}
88 1 Loïc Dachary
}
89
</pre>
90 2 Loïc Dachary
91 48 Nathan Cutler
h4. Notes on the ceph-backport.sh script
92 2 Loïc Dachary
93 48 Nathan Cutler
The ceph-backport.sh script:
94
95
* creates a pull request from the <code>wip-$issue-$release</code> branch with the same title as the issue
96 1 Loïc Dachary
<pre>
97
account=myaccount
98
eval title=$(curl --silent 'http://tracker.ceph.com/issues/'$issue.json?key=$redmine_key | jq .issue.subject) ; echo $title
99
number=$(curl --silent --data-binary '{"title":"'"$title"'","head":"'$account':wip-'$issue-$release'","base":"'$release'","body":"http://tracker.ceph.com/issues/'$issue'"}' 'https://api.github.com/repos/ceph/ceph/pulls?access_token='$github_token | jq .number)
100 11 Loïc Dachary
</pre>
101 48 Nathan Cutler
* assigns the pull request to yourself (because it needs to got through integration tests before it can be approved by the original author), add the relevant labels (rgw, core, bug fix, feature...) and set the milestone to $release (requires write permission to the ceph repository)
102 11 Loïc Dachary
<pre>
103 18 Loïc Dachary
component=core ; curl --silent --data-binary '{"milestone":"'$release_number'","assignee":"'$account'","labels":["bug fix","'$component'"]}' 'https://api.github.com/repos/ceph/ceph/issues/'$number'?access_token='$github_token
104 25 Nathan Cutler
</pre>
105 48 Nathan Cutler
* Sets the issue description to only contain the URL to the pull request and change the status to *In Progress*
106 1 Loïc Dachary
<pre>
107 28 Nathan Cutler
redmine_status=2 # In Progress
108
curl --verbose -X PUT --header 'Content-type: application/json' --data-binary '{"issue":{"description":"https://github.com/ceph/ceph/pull/'$number'","status_id":'$redmine_status'}}' 'http://tracker.ceph.com/issues/'$issue.json?key=$redmine_key
109 10 Loïc Dachary
</pre>
110
111 17 Nathan Cutler
Here are the snippets above grouped together for easier copy/paste:
112 10 Loïc Dachary
<pre>
113 33 Nathan Cutler
set -x
114 10 Loïc Dachary
redmine_key=b586c588d4333
115 30 Loïc Dachary
redmine_user_id=789 # as found in the URL near "Logged in as " top right of each page
116 10 Loïc Dachary
github_token=bc275830c635
117 12 Loïc Dachary
github_user=dachary
118 10 Loïc Dachary
issue=$1
119
# can't seem to extract the release number with the api
120
release=giant ; release_number=2
121 1 Loïc Dachary
release=firefly ; release_number=3
122
release=hammer ; release_number=5
123
release=infernalis ; release_number=7
124 38 Loïc Dachary
release=jewel ; release_number=8
125
#release_branch=$release-next
126
release_branch=$release
127 33 Nathan Cutler
if [ $(curl --silent http://tracker.ceph.com/issues/$issue.json | jq -r .issue.tracker.name) != "Backport" ]
128
then
129
    echo "not a backport issue"
130
    exit 1
131 1 Loïc Dachary
fi
132 38 Loïc Dachary
git checkout -f -b wip-$issue-$release ceph/$release_branch
133 10 Loïc Dachary
git cherry-pick -x .....
134 1 Loïc Dachary
git push loic wip-$issue-$release ; sleep 2 # let github catch up
135
title=$(curl --silent 'http://tracker.ceph.com/issues/'$issue.json?key=$redmine_key | jq .issue.subject | tr -d '\\"')
136 17 Nathan Cutler
echo "Issue title: $title"
137 38 Loïc Dachary
number=$(curl --silent --data-binary '{"title":"'"$title"'","head":"'$github_user':wip-'$issue-$release'","base":"'$release_branch'","body":"http://tracker.ceph.com/issues/'$issue'"}' 'https://api.github.com/repos/ceph/ceph/pulls?access_token='$github_token | jq .number)
138 1 Loïc Dachary
echo "Opened pull request $number"
139
component=core ; curl --silent --data-binary '{"milestone":"'$release_number'","assignee":"'$github_user'","labels":["bug fix","'$component'"]}' 'https://api.github.com/repos/ceph/ceph/issues/'$number'?access_token='$github_token
140 12 Loïc Dachary
firefox https://github.com/ceph/ceph/pull/$number
141 1 Loïc Dachary
redmine_status=2 # In Progress
142 30 Loïc Dachary
curl --verbose -X PUT --header 'Content-type: application/json' --data-binary '{"issue":{"description":"https://github.com/ceph/ceph/pull/'$number'","status_id":'$redmine_status',"assigned_to_id":'$redmine_user_id'}}' 'http://tracker.ceph.com/issues/'$issue.json?key=$redmine_key
143 10 Loïc Dachary
firefox http://tracker.ceph.com/issues/$issue
144
</pre>
145 26 Nathan Cutler
146 29 Loïc Dachary
If you would like to automate update of the tracker target version, try something like this instead of the last <code>curl</code> command:
147 26 Nathan Cutler
<pre>
148
curl --verbose -X PUT --header 'Content-type: application/json' --data-binary '{"issue":{"description":"https://github.com/ceph/ceph/pull/'$number'","status_id":'$redmine_status',"fixed_version_id":'$redmine_fixed_version'}}' 'http://tracker.ceph.com/issues/'$issue.json?key=$redmine_key
149
</pre>
150 27 Nathan Cutler
The values of <code>$redmine_status</code> and <code>$redmine_fixed_version</code> can be determined by setting the desired values in an issue and then peeking at the JSON using a command like this:
151
<pre>
152
curl --silent 'http://tracker.ceph.com/issues/12395.json'
153
</pre>