Bug #89583 no rpm build instructions from source git tree
Submitted: 8 Feb 2018 7:34 Modified: 9 Feb 2018 8:33
Reporter: Simon Mudd (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Packaging Severity:S4 (Feature request)
Version:8.0.4 OS:CentOS (7)
Assigned to: CPU Architecture:Any
Tags: build from git source, consistency, packaging, repeatable builds, rpm

[8 Feb 2018 7:34] Simon Mudd
Description:
I recently filed https://github.com/mysql/mysql-server/pull/198 which is to allow me to be able to rebuild src rpm packages with a tag in the rpm name that gets generated which allows me to be able to distinguish my home built rpms from those built by Oracle.

I wanted to actually test this but until 8.0.5 or later has the patch I can't test directly building from any src rpms as Oracle hasn't yet applied the patch.

So my desire is to build from a git tree (e.g. the latest 8.0.4 tag with my patch) some rpms (including the src rpm) so that I can test the whole process works.

I find no documentation on how to build the rpms, nor do I see any scripts in the git repo which do this.

How to repeat:
Clone the mysql server git repo from github, checkout 8.0 branch and then look to see how to build an rpm. (in my case using the rpm-oel spec file.)

Fail to find any instructions.

I tried to do this myself and have almost completed the process but it doesn't quite work yet. Here are some observations.

1. do a normal build which makes the spec file along the lines of:

$ mkdir bld; (  cd bld; cmake -DDOWNLOAD_BOOST=1 -DWITH_BOOST=../boost-temporary ..;  make )

2. add required software to SOURCES directory (needed for rpm build):

$ git archive --format=tar --prefix=mysql-8.0.4-rc/ sjmudd/rpm_release_extra | gzip -9 > $HOME/rpmbuild/SOURCES/mysql-8.0.4-rc.tar.gz  # this is my patched branch
$ git archive --format=tar --prefix=mysql-5.6.37/ mysql-5.6.37 | gzip -9 > $HOME/rpmbuild/SOURCES/mysql-5.6.37.tar.gz
$ (cd boost-temporary && tar cvjf $HOME/rpmbuild/SOURCES/boost_1_65_0.tar.bz2 boost_1_65_0 )
$ cp packaging/rpm-common/{filter-provides.sh,/filter-requires.sh} $HOME/rpmbuild/SOURCES/

This leads to failures due to missing files (from the 8.0.4 tar ball):

* mysql-8.0.4-rc/Docs/ChangeLog
* mysql-8.0.4-rc/Docs/INFO_SRC*
* various missing man pages, e.g.:    File not found by glob: $HOME/rpmbuild/BUILDROOT/mysql-community-8.0.4-0.1.rc.el7.centos.x86_64/usr/share/man/man1/innochecksum.1*

Oracle have produced 8.0.4 community rpms for this DMR release so clearly they have built the rpms but not this way. How did you do this?

Suggested fix:
I'm sure that with a bit of extra poking I'll manage to fix this by either adjusting the spec file, or munging things to make it work.

I would like to see that this process is:
(1) documented
(2) scriptable so we can do this without thinking and thus can be sure the process works

It would be good to ensure the same is true of the 5.7 rpms for similar reasons.

Having to depend on being given src rpms to rebuild them properly is wrong. I should be able to build these rpms easily from the git tree, and thus test patches I propose. I understand that the rpm build process is complicated by the fact you need to provide "old compatibility" libraries but that doesn't mean the process can't be documented so others apart from Oracle can do this.  The whole point of rpm builds is to make them reproducible so it seems surprising that I can't build the rpms "from source" in an obvious and straight-forward way.
[8 Feb 2018 8:12] Daniël van Eeden
Note that "make package" is the official way to build the tar.gz iirc.
https://dev.mysql.com/doc/mysql-sourcebuild-excerpt/5.7/en/installing-source-distribution....
[8 Feb 2018 10:46] Simon Mudd
Running make package actually only does the following:

...
[100%] Built target my_safe_process
Run CPack packaging tool...
CPack: Create package using TGZ
CPack: Install projects
CPack: - Run preinstall target for: MySQL
CPack: - Install project: MySQL
CPack: Create package
CPack: - package: $HOME/mysql-server/bld/mysql-8.0.4-rc-linux-x86_64.tar.gz generated.

It makes a _binary_ tar ball, not a rpm src or binary package, so does not resolve the issue
I'm discussing.

An extra make rpm target which produces src and rpm packages would be quite nice, but at least providing documentation on the process, as requested in this bug report, would be a good start.
[8 Feb 2018 10:47] Simon Mudd
Adjust OS to indicate platform I'm using: CentOS 6/7 [ should be the same as RHEL or OEL ], but this is also applicable to other "rpm" environments like SuSE and Fedora.
[8 Feb 2018 11:57] Simon Mudd
Adjust synopsis to correctly reference "git tree"
[8 Feb 2018 13:07] Terje Røsten
The best approach is what Linux distros does: 
they create patches against vanilla tarball.

1) Download the SRPM which matches your working tree in git best.
2) Create a patch between version provided in the source tarball in the SRPM
and your working tree in git.
3) Add patch to .spec file by adding required PatchX: ... in header and
%patchX ... in %prep section
4) Rebuild

Btw: regarding #198, there is no need for more tags, just use the dist tag already provided:

Use:

$ rpmbuild --rebuild --define 'dist .mybuild.el7' mysql-community-5.7.21-1.el7.src.rpm

and RPM will end up as:

 mysql-community-5.7.21-1.mybuild.el7.x86_64.rpm
[8 Feb 2018 15:41] Simon Mudd
Hi Terje:

I'd prefer _not_ to [ab]use the _dist tag as I'd rather not touch it, or worry about the value it has. That's figured out by the current process of making the rpm I assume. Let me add an optional way of making this change. It's cleaner, may be used infrequently, but doesn't interfere with any existing behaviour. So if I build on RHEL6/7 or on SuSE or on Fedora or any new rpm distribution I don't have to worry about what Oracle has done in the spec file.

The request for a separate tag is there for a reason, even if Oracle will never be expected to use it.
[8 Feb 2018 16:00] Simon Mudd
Regarding your comment about how to build a src rpm I'm fully aware of how this can be done.

The thing I was trying to point out was that "the source" comes from the github.com/mysql/mysql-server git tree and I want to be able to build the src.rpm (and binaries) directly from the "source" without patching.  If I need to patch then it shows that the rpms being built are not being built from the same source as I'm using.  It also means that if I apply a local patch I should be able to build the packages exactly the way you do with my changes applied. This reduces the chances of difference in "building" from changes in the source code and nothing else.

Thus I was trying to generate the "sources" that the mysql.spec file required and build from that. Extra patches should not be needed in this situation.

Clearly when trying to provide the appropriate files, needed by the spec file, most seem to be available from the git tree but clearly things are missing.  This means that I can't build (unless you show me how) my rpms in exactly the same way you do. That's my goal. Once I can do that I can _modify_ them to include local patches which should an issue come up allows me to specify the change that's been made and should someone at Oracle want to try to reproduce "my problem" they'll be able to do that as we will be both building the same thing.

However it works the other way too: my patches, which fix or improve something, if run on systems which I build the same way as you mean that they'll be much more likely to work when you build the server than otherwise.

So my PR still stands for the reasons specified and I'd also like to be able to build src/binary rpms from the github.com/mysql/mysql-server git tree using a repeatable procedure. It would be nice if you can provide information on how that can be done.
[8 Feb 2018 17:22] Simon Mudd
So let's be clear. I downloaded your 8.0.4-rc src rpm for RHEL7. I installed it to provide me with the "sources" and I then compared these sources with the 8.0.4 tarball created from the git tree to see what difference there might be. Basically I did this:

$ diff -uNr oracle/mysql-8.0.4-rc sjmudd/mysql-8.0.4-rc | diffstat

The output shows a huge number of differences:

 .gitreview                                                            |   26
 Docs/ChangeLog                                                        |27250 ------
 Docs/INFO_BIN                                                         |   90
 Docs/INFO_SRC                                                         |    9
 Docs/mysql.info                                                       |    3
 man/comp_err.1                                                        |  263
 man/ibd2sdi.1                                                         |  482
 man/innochecksum.1                                                    | 1030
 man/lz4_decompress.1                                                  |  117
 man/my_print_defaults.1                                               |  235
 man/myisam_ftdump.1                                                   |  266
 man/myisamchk.1                                                       | 2470
 man/myisamlog.1                                                       |  243
 man/myisampack.1                                                      |  839
 man/mysql.1                                                           | 3731
 man/mysql.server.1                                                    |  435
 man/mysql_config.1                                                    |  271
 man/mysql_config_editor.1                                             | 1091
 man/mysql_secure_installation.1                                       |  397
 man/mysql_ssl_rsa_setup.1                                             |  477
 man/mysql_tzinfo_to_sql.1                                             |  136
 man/mysql_upgrade.1                                                   |  910
 man/mysqladmin.1                                                      | 1322
 man/mysqlbinlog.1                                                     | 3045
 man/mysqlcheck.1                                                      | 1064
 man/mysqld.8                                                          |   76
 man/mysqld_multi.1                                                    |  658
 man/mysqld_safe.1                                                     | 1000
 man/mysqldump.1                                                       | 2904
 man/mysqldumpslow.1                                                   |  332
 man/mysqlimport.1                                                     |  881
 man/mysqlpump.1                                                       | 2298
 man/mysqlshow.1                                                       |  742
 man/mysqlslap.1                                                       | 1147
 man/perror.1                                                          |  192
 man/resolve_stack_dump.1                                              |  136
 man/resolveip.1                                                       |  117
 man/zlib_decompress.1                                                 |  117
 mysql-test/collections/default.daily                                  |    2
 mysql-test/collections/default.daily-valgrind                         |    2
 mysql-test/collections/default.experimental                           |    6
 mysql-test/collections/default.push                                   |    2
 mysql-test/collections/default.push-valgrind                          |    1
 mysql-test/collections/default.release                                |   19
 mysql-test/collections/default.release.done                           |    1
 mysql-test/collections/default.weekly                                 |   11
 mysql-test/collections/default.weekly-valgrind                        |    2
 mysql-test/collections/default.weekly.basic                           |    2
 mysql-test/collections/mysql-8.0-stage.push                           |    2
 mysql-test/collections/mysql-trunk-stage.push                         |    2
 mysql-test/collections/mysql-trunk-xplugin.push                       |    3
 mysql-test/collections/mysql-trunk-xplugin.push-valgrind              |    2
 packaging/rpm-docker/mysql.spec.in                                    |    2
 packaging/rpm-fedora/mysql.spec.in                                    |    2
 packaging/rpm-oel/mysql.spec.in                                       |    2
 packaging/rpm-sles/mysql.spec.in                                      |    2
 rapid/plugin/group_replication/tests/collections/FilesCopied          |   11
 rapid/plugin/x/tests/collections/FilesCopied                          |   12
 scripts/fill_help_tables.sql                                          | 2904
 sql/sql_hints.yy.cc                                                   | 2413
 sql/sql_hints.yy.h                                                    |  146
 sql/sql_yacc.cc                                                       |44449 ----------
 sql/sql_yacc.h                                                        | 1525
 storage/ndb/ndbapi-examples/mgmapi_logevent/Makefile                  |   45
 storage/ndb/ndbapi-examples/mgmapi_logevent2/Makefile                 |   45
 storage/ndb/ndbapi-examples/ndbapi_async/Makefile                     |   45
 storage/ndb/ndbapi-examples/ndbapi_async1/Makefile                    |   44
 storage/ndb/ndbapi-examples/ndbapi_blob/Makefile                      |   45
 storage/ndb/ndbapi-examples/ndbapi_blob_ndbrecord/Makefile            |   45
 storage/ndb/ndbapi-examples/ndbapi_event/Makefile                     |   45
 storage/ndb/ndbapi-examples/ndbapi_recattr_vs_record/Makefile         |   45
 storage/ndb/ndbapi-examples/ndbapi_retries/Makefile                   |   44
 storage/ndb/ndbapi-examples/ndbapi_s_i_ndbrecord/Makefile             |   45
 storage/ndb/ndbapi-examples/ndbapi_scan/Makefile                      |   45
 storage/ndb/ndbapi-examples/ndbapi_simple/Makefile                    |   45
 storage/ndb/ndbapi-examples/ndbapi_simple_dual/Makefile               |   45
 storage/ndb/ndbapi-examples/ndbapi_simple_index/Makefile              |   45
 storage/ndb/src/common/transporter/failoverSCI/Makefile               |   41
 storage/ndb/src/common/util/testConfigValues/Makefile                 |   35
 storage/ndb/src/common/util/testProperties/Makefile                   |   32
 storage/ndb/src/common/util/testSimpleProperties/Makefile             |   35
 storage/ndb/src/kernel/vm/testCopy/Makefile                           |   32
 storage/ndb/src/kernel/vm/testDataBuffer/Makefile                     |   33
 storage/ndb/src/kernel/vm/testSimplePropertiesSection/Makefile        |   33
 storage/ndb/src/mgmclient/test_cpcd/Makefile                          |   40
 storage/ndb/test/crund/Makefile                                       |   65
 storage/ndb/test/crund/helpers/Makefile                               |   22
 storage/ndb/test/crund/helpers/src/utils/Makefile                     |  210
 storage/ndb/test/crund/schema_driven_load_unfinished/tws_cpp/Makefile |   85
 storage/ndb/test/crund/src/cpp/Makefile                               |   83
 support-files/MacOSX/ReadMe.html                                      |  405
 91 files changed, 1492 insertions(+), 108614 deletions(-)
[8 Feb 2018 17:22] Simon Mudd
The missing Changelog is clearly in the tar ball used in the src rpm (but not in the git repo), the missing man pages are in the tarball used to make the src rpm (but either not in the git repo or the spec file is broken). The Makefiles seem not to be present in the Oracle supplied tar ball.  Either way building a mysql-8.0.4.tar.gz file from git does not give the same tarball as that provided in the src rpm for 8.0.4-rc. That doesn't make sense to me.

This seems to suggest that the github source tree is not the one used to build the rpms. That's a concern as I then ask how can I build src rpms if I don't have those provided by Oracle?  The suggestion to use patches and apply in the spec file is pre-git. The sources are supposed to be in the git tree so just tell me how I can use that to produce the files needed to make the rpm SOURCES.

Without that information only Oracle can build src rpms and no-one else can repeat the process they use and any changes required by people building rpms can't be done in a separate branch of a cloned copy of github.com/mysql/mysql-server. That would be better as from there I can much more easily provide PRs which should improve the MySQL sources.
[8 Feb 2018 18:52] Simon Mudd
One comment about the proposed 'release_extra' tag for allowing rpms to be built with an "adjusted name".  If accepted this needs to be documented as otherwise it will be cryptic magic which no-one understands etc and that would not be good.

However, I have no clue as to where would be the appropriate place to document this.
I'm not too sure, as you see from this bug report / feature request, as to exactly the right way to build rpms from the src git tree, and it would seem that that bit of documentation should cover this extra setting. However, I'm not sure if such documentation exists (yet) or where it is.

So even more reason to document this whole process and make it transparent.
[8 Feb 2018 18:52] Simon Mudd
Changing to S4 - feature request as nothing is actually broken.
[9 Feb 2018 8:33] MySQL Verification Team
Thank you for the report and feedback.
Verifying as a feature request to document this whole process.

Thanks,
Umesh