Willy Tarreau | ba4ad17 | 2019-06-15 21:53:40 +0200 | [diff] [blame^] | 1 | HAProxy branches and life cycle |
| 2 | =============================== |
| 3 | |
| 4 | The HAProxy project evolves quickly to stay up to date with modern features |
| 5 | found in web environments but also takes a great care of addressing bugs which |
| 6 | may affect deployed versions without forcing such users to upgrade when not |
| 7 | needed. For this reason the project is developed in branches. |
| 8 | |
| 9 | A branch is designated as two numbers separated by a dot, for example "1.8". |
| 10 | This numbering is historical. Each new development cycle increases the second |
| 11 | digit by one, and after it reaches '9' it goes back to zero and the first digit |
| 12 | increases by one. It effectively grows as a decimal number increased by 0.1 per |
| 13 | version. |
| 14 | |
| 15 | The complete version is made of the branch suffixed with "-dev" followed by a |
| 16 | sequence number during development, then by "." followed by a number when the |
| 17 | development of that branch is finished and the branch enters a maintenance |
| 18 | phase. The first release of a branch starts at ".0". Immediately after ".0" is |
| 19 | issued, the next branch is created as "-dev0" as an exact copy of the previous |
| 20 | branch's ".0" version. Thus we observe the following development sequence: |
| 21 | |
| 22 | ... 1.9-dev10 -> 1.9-dev11 -> 1.9.0 -> 2.0-dev0 -> 2.0-dev1 ... 2.0 -> ... |
| 23 | |
| 24 | Occasionally a series of "-rc" versions may be emitted between the latest -dev |
| 25 | and the release to mark the end of development and start of stabilizing, though |
| 26 | it's mostly a signal send to users that the release is approaching rather than |
| 27 | a change in the cycle as it is always hard to categorize patches. |
| 28 | |
| 29 | Very often the terms "branch" and "version" will be used interchangeably with |
| 30 | only the first two digits to designate "the latest version of that branch". So |
| 31 | when someone asks you "Could you please try the same on 1.8", it means "1.8.X" |
| 32 | with X as high as possible, thus for example 1.8.20 if this one is available at |
| 33 | this moment. |
| 34 | |
| 35 | During the maintenance phase, a maintenance branch is created for the just |
| 36 | released version. The development version remains in the development branch |
| 37 | called "master", or sometimes "-dev". If branches are represented vertically |
| 38 | and time horizontally, this will look like this: |
| 39 | |
| 40 | versions branch |
| 41 | 1.9-dev10 1.9-dev11 1.9.0 2.0-dev0 2.0-dev1 2.0-dev2 |
| 42 | ----+--------+---------+-------+---------+---------+----------> master |
| 43 | \ |
| 44 | \ 1.9.1 1.9.2 |
| 45 | `-----------+-------------+---------> 1.9 |
| 46 | |
| 47 | Each released version (e.g. 1.9.0 above) appears once in the master branch so |
| 48 | that it is easy to list history of changes between versions. |
| 49 | |
| 50 | Before version 1.4, development and maintenance were inter-mixed in the same |
| 51 | branch, which resulted in latest maintenance branches becoming unstable after |
| 52 | some point. This is why versions 1.3.14 and 1.3.15 became maintenance branches |
| 53 | on their own while the development pursued on 1.3 to stabilize again in the |
| 54 | latest versions. |
| 55 | |
| 56 | Starting with version 1.4.0, a rule has been set not to create new features |
| 57 | into a maintenance branch. It was not well respected and still created trouble |
| 58 | with certain 1.4 versions causing regressions and confusing users. |
| 59 | |
| 60 | Since 1.5.0 this "no new feature" rule has become strict and maintenance |
| 61 | versions only contain bug fixes that are necessary in this branch. This means |
| 62 | that any version X.Y.Z is necessarily more stable than X.Y.W with W<Z. |
| 63 | |
| 64 | For this reason there is absolutely no excuse for not updating a version within |
| 65 | your branch, as your version necessarily contains bugs that are fixed in any |
| 66 | later version in that same branch. Obviously when a branch is just released, |
| 67 | there will be some occasional bugs. And once in a while a fix for a recently |
| 68 | discovered bug may have an undesired side effect called a regression. This must |
| 69 | never happen but this will happen from time to time, especially on recently |
| 70 | released versions. This is often presented as an excuse by some users for not |
| 71 | updating but this is wrong, as the risk staying with an older version is much |
| 72 | higher than the risk of updating. If you fear there could be an issue with an |
| 73 | update because you don't completely trust the version in your branch, it simply |
| 74 | means you're using the wrong branch and need an older one. |
| 75 | |
| 76 | When a bug is reported in a branch, developers will systematically ask if the |
| 77 | bug is present in the latest version of this branch (since developers don't |
| 78 | like to work on bugs that were already fixed). It's a good practice to perform |
| 79 | the update yourself and to test again before reporting the bug. Note, as long |
| 80 | as you're using a supported branch, as indicated on the haproxy.org web site, |
| 81 | you don't need to upgrade to another branch to report a bug. However from time |
| 82 | to time it may happen that a developer will ask you if you can try it in order |
| 83 | to help narrow the problem down. But this will never be a requirement, just a |
| 84 | question. |
| 85 | |
| 86 | Once a bug is understood, it is tested on the development branch and fixed |
| 87 | there. Then the fix will be applied in turn to older branches, jumping from |
| 88 | one to the other in descending order. For example: |
| 89 | |
| 90 | FIX |
| 91 | 2.0-dev4 HERE 2.0-dev5 2.0-dev6 |
| 92 | -----+-------V-------------+-----------+--------------> master |
| 93 | 1.9.4 \ 1.9.5 1.9.6 1.9.7 |
| 94 | --+------------o-------+---------+-------------+------> 1.9 |
| 95 | 1.8.18 \ 1.8.19 1.8.20 |
| 96 | -----+-----------o------------+-------------+---------> 1.8 |
| 97 | |
| 98 | This principle ensures that you will always have a safe upgrade path from an |
| 99 | older branch to a newer: under no circumstances a bug that was already fixed |
| 100 | in an older branch will still be present in a newer one. In the diagram above, |
| 101 | a bug reported for 1.8.18 would be fixed between 2.0-dev4 and 2.0-dev5. The |
| 102 | fix will be backported into 1.9 and from there into 1.8. 1.9.5 will be issued |
| 103 | with the fix before 1.8.19 will be issued. This guarantees that for any version |
| 104 | 1.8 having the fix, there always exists a version 1.9 with it as well. So if |
| 105 | you would upgrade to 1.8.19 to benefit from the fix and the next day decide |
| 106 | that for whatever new feature you need to upgrade to 1.9, you'll have 1.9.5 |
| 107 | available with the same set of fixes so you will not reintroduce a previously |
| 108 | fixed problem. |
| 109 | |
| 110 | In practice, it takes longer to release older versions than newer ones. There |
| 111 | are two reasons to this. One is technical: the fixes often require some |
| 112 | adaptations to be done for older versions. The other reason is stability: in |
| 113 | spite of the great care and the tests, there is always a faint risk that a fix |
| 114 | introduces a regression. By leaving fixes exposed in more recent versions |
| 115 | before appearing in older ones, there is a much smaller probability that such a |
| 116 | regression remains undetected when the next version of the older branch is |
| 117 | issued. |
| 118 | |
| 119 | So the rule for the best stability is very simple: |
| 120 | |
| 121 | STICK TO THE BRANCH THAT SUITS YOUR NEEDS AND APPLY ALL UPDATES. |
| 122 | |
| 123 | With other projects, some people developed a culture of backporting only a |
| 124 | selection of fixes into their own maintenance branch. Usually they consider |
| 125 | these fixes are critical, or security-related only. THIS IS TERRIBLY WRONG. |
| 126 | It is already very difficult for the developers who made the initial patch to |
| 127 | figure if and how it must be backported to an older branch, what extra patches |
| 128 | it depends on to be safe, as you can imagine it is impossible for anyone else |
| 129 | to make a safe guess about what to pick. |
| 130 | |
| 131 | A VERSION WHICH ONLY CONTAINS A SELECTION OF FIXES IS WAY MORE |
| 132 | DANGEROUS AND LESS STABLE THAN ONE WITHOUT ANY OF THESE FIXES. |
| 133 | |
| 134 | Branches up to 1.8 are all designated as "long-term supported" ("LTS" for |
| 135 | short), which means that they are maintained for several years after the |
| 136 | release. These branches were emitted at a pace of one per year since 1.5 in |
| 137 | 2014. As of 2019, 1.5 is still supported and widely used, eventhough it very |
| 138 | rarely receives updates. After a few years these LTS branches enter a |
| 139 | "critical fixes only" status, which means that they will rarely receive a fix |
| 140 | but if that a critital issue affects them, a release will be made, with or |
| 141 | without any other fix. Once a version is not supported anymore, it will not |
| 142 | receive any fix at all and it will really be time for you to upgrade to a more |
| 143 | recent branch. Please note that even when an upgrade is needed, a great care is |
| 144 | given to backwards compatibility so that most configs written for version 1.1 |
| 145 | still work with little to no modification 16 years later on version 2.0. |
| 146 | |
| 147 | Since 1.9, the release pacing has increased to match faster moving feature sets |
| 148 | and a faster stabilization of the technical foundations. The principle is now |
| 149 | the following: |
| 150 | - one release is emitted between October and December, with an odd version |
| 151 | number (such as "1.9"). This version heavily focuses on risky changes that |
| 152 | are considered necessary to develop new features. It can for example bring |
| 153 | nice performance improvements as well as invisible changes that will serve |
| 154 | later ; these versions will only be emitted for developers and highly |
| 155 | skilled users. They will not be maintained for a long time, they will |
| 156 | receive updates for 12 to 18 months only after which they will be marked |
| 157 | End-Of-Life ("EOL" for short). They may receive delicate fixes during their |
| 158 | maintenance cycle so users have to be prepared to see some breakage once in |
| 159 | a while as fixes are stabilizing. THESE VERSIONS MUST ABSOLUTELY NOT BE |
| 160 | PACKAGED BY OPERATING SYSTEM VENDORS. |
| 161 | |
| 162 | - one release is emitted between May and June, with an even version number |
| 163 | (such as "2.0"). This version mostly relies on the technical foundations |
| 164 | brought by the previous release and tries hard not to apply risky changes. |
| 165 | Instead it will bring new user-visible features. Such versions will be |
| 166 | long-term supported and may be packaged by operating system vendors. |
| 167 | |
| 168 | This development model provides better stability for end users and better |
| 169 | feedback for developers: |
| 170 | - regular users stick to LTS versions which rely on the same foundations |
| 171 | as the previous releases that had 6 months to stabilize. In terms of |
| 172 | stability it really means that the point zero version already accumulated |
| 173 | 6 months of fixes and that it is much safer to use even just after it is |
| 174 | released. |
| 175 | |
| 176 | - for developers, given that the odd versions are solely used by highly |
| 177 | skilled users, it's easier to get advanced traces and captures, and there |
| 178 | is less pressure during bug reports because there is no doubt the user is |
| 179 | autonomous and knows how to work around the issue or roll back to the last |
| 180 | working version. |
| 181 | |
| 182 | Thus the release cycle from 1.8 to 2.2 should look like this: |
| 183 | |
| 184 | 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 |
| 185 | --+---------------+---------------+--------------+--------------+----> master |
| 186 | \ \ \ \ \ |
| 187 | \ \ \ \ `--> 2.2 LTS |
| 188 | \ \ \ `--+--+--+---+---> 2.1 |
| 189 | \ \ `----+-----+------+-------+----> 2.0 LTS |
| 190 | \ `--+-+-+--+---+------+--------+-----| EOL 1.9 |
| 191 | `---+---+---+-----+-------+-----------+---------------+------> 1.8 LTS |
| 192 | |
| 193 | In short the non-LTS odd releases can be seen as technological previews of the |
| 194 | next feature release, and will be terminated much ealier. The plan is to barely |
| 195 | let them overlap with the next non-LTS release, allowing advanced users to |
| 196 | always have the choice between the last two major releases. |
| 197 | |
| 198 | With all this in mind, what version should you use ? It's quite simple: |
| 199 | - if you're a first-time HAProxy user, just use the version provided by your |
| 200 | operating system. Just take a look at the "known bugs" section on the |
| 201 | haproxy.org web site to verify that it's not affected by bugs that could |
| 202 | have an impact for you. |
| 203 | |
| 204 | - if you don't want or cannot use the version shipped with your operating |
| 205 | system, it is possible that other people (including the package maintainer) |
| 206 | provide alternate versions. This is the case for Debian and Ubuntu for |
| 207 | example, where you can choose your distribution and pick the branch you |
| 208 | need here: https://haproxy.debian.net/ |
| 209 | |
| 210 | - if you want to build with specific options, apply some patches, you'll |
| 211 | have to build from sources. If you have little experience or are not |
| 212 | certain to devote regular time to perform this task, take an "old" branch |
| 213 | (i.e. 1-2 years old max, for example 1.8 when 2.0 is emitted). You'll avoid |
| 214 | most bugs and will not have to work too often to update your local version. |
| 215 | |
| 216 | - if you need a fresh version for application development, or to benefit from |
| 217 | latest improvements, take the most recent version of the most recent branch |
| 218 | and keep it up to date. You may even want to use the Git version or nightly |
| 219 | snapshots. |
| 220 | |
| 221 | - if you want to develop on HAProxy, use the master from the Git tree. |
| 222 | |
| 223 | - if you want to follow HAProxy's development by doing some tests without |
| 224 | the burden of entering too much into the development process, just use the |
| 225 | -dev versions of the master branch. At some point you'll feel the urge to |
| 226 | switch to the Git version anyway as it will ultimately simplify your work. |
| 227 | |
| 228 | - if you're installing it on unmanaged servers with little to no hostile |
| 229 | exposure, or your home router, you should pick the latest version in one |
| 230 | of the oldest supported branches. While it doesn't guarantee that you will |
| 231 | never have to upgrade it, at least as long as you don't use too complex a |
| 232 | setup, it's unlikely that you will need to update it often. |
| 233 | |
| 234 | And as a general rule, do not put a non-LTS version on a server unless you are |
| 235 | absolutely certain you are going to keep it up to date yourself and already |
| 236 | plan to replace it once the following LTS version is issued. If you are not |
| 237 | going to manage updates yourself, use pre-packaged versions exclusively and do |
| 238 | not expect someone else to have to deal with the burden of building from |
| 239 | sources. |