The costs of forks
The perils of code forks are well-known within free software communities: as the code diverges, fixes and new features are only applied to one branch or the other, which leads to further divergence—and bugs that persist far too long. The Fuel project, which is a graphical user interface (GUI) to help deploy, test, and manage OpenStack installations, has seemingly learned that lesson anew.
A request from Emilien Macchi for more collaboration between Fuel and the Puppet OpenStack project kicked off the discussion. Puppet is a configuration management utility that is used by Fuel to assist in deploying OpenStack. But Fuel has forked some of the Puppet modules it uses from the Puppet OpenStack project—which creates Puppet modules for OpenStack components—into its Fuel Library repository. Macchi noted a number of problems with how that has been handled over the last two years.
He listed three areas of concern. Bugs are reported against Fuel and fixed there, but the fixes fail to propagate back to the Puppet OpenStack modules. Sometimes fixes are submitted to Puppet OpenStack, but without tests and without any push to get them committed because they have already been fixed in Fuel. Finally, code is moving from the modules into Fuel but not using mechanisms that would maintain the history and author attribution of the patches (e.g. using Git merges). Macchi suggested that working together would be beneficial:
Matthew Mosesohn explained that
Fuel was acting similar to other OpenStack projects with regard to forking
and bundling other components into its repositories. It may not be "the
most community-oriented approach
", but it is part of what allowed
Fuel to stabilize and mature, he said.
The directory structure in the Fuel Library makes it difficult to directly
merge from the upstream modules, he said.
Fixes not flowing from Fuel to Puppet OpenStack is a problem, Mosesohn
continued.
The Fuel team has a policy adopted
back in October that patches to the Puppet OpenStack modules will not be
merged unless they have been
submitted upstream or an upstream bug has been filed. Lastly, he suggested
that bugs
found in the modules that had already been reported or fixed in Fuel should
result in a ping on the Fuel IRC channel "and we can try to
figure out how to get this applied upstream correctly
".
But Thomas Goirand (and others) found that to be a bit backward. Fuel is the downstream project and should pursue an "upstream first" strategy:
For his part, Macchi welcomed the discussion, but also felt that Mosesohn and the Fuel project were approaching the problems from the wrong direction.
Macchi and Dmitry Borodaenko (who picked up the discussion on the Fuel project's side) seem to have a fundamental disagreement about two things. Macchi is unhappy that the commit history is getting lost when Fuel does large copy-and-paste patches from the Puppet modules; he mentions possible license issues, but that is really a red herring, as Borodaenko pointed out. However, as James Bottomley described, forks of that nature build up a huge technical debt that can be enormously expensive to unwind:
The other area of contention is about what level of responsibility the Fuel project and its developers should have to not simply submit their patches upstream, but to respond to the comments, respin the patches, and shepherd them through the process of getting them into Puppet OpenStack. Borodaenko suggested that the Puppet OpenStack team take over that role as needed. He asked about finding a middle ground, perhaps:
But Macchi would rather see Fuel developers working in the upstream project. The Puppet OpenStack team would be happy to help Fuel developers get involved with its community, as that was Macchi's goal in starting the thread. But the team does not just want to pick up whatever Fuel submits:
This is definitely not how OpenStack works.
As it turns out, the divide is not as big as it might seem. Borodaenko is on-board with the overall goal of having Fuel use the upstream Puppet OpenStack modules directly; the difference is mostly about how to get there. In fact, he advocated working more closely with the Puppet OpenStack upstream back in March 2014. His concern is that overcommitting the Fuel project developers too quickly will not succeed:
Other Fuel project members (including Andrew Woodward and Bogdan Dobrelya) were largely in agreement with Macchi, Goirand, and others that "upstream first" is really the only workable approach. Dobrelya has also taken some concrete steps to combat the problem, including changing the documentation to strongly discourage any additional forks of Puppet modules. It is not the kind of change that can happen overnight but, by the sounds, it is one that has lingered for too long—to the point where some momentum for a change has built up.
It is sometimes easy for development projects to get so wrapped up in solving their own problems that they forget to occasionally look up and evaluate their relationship with the rest of the ecosystem. That appears to be what happened here at some level. The problem has been known and discussed at various summits over the years, but little has changed. With luck, that should not be the case anymore.
For the most part, the "evils" of one-way forks were already known to the Fuel developers from the experiences of other projects over the years. But it can be easy to fall into the trap; thanks to Macchi's note, the process of extricating the project from it has begun in earnest.
