Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use base image for all compiler version #204

Closed
wants to merge 21 commits into from

Conversation

uilianries
Copy link
Member

@uilianries uilianries commented May 22, 2020

Changelog: Feature: Add new Docker images based on Xenial

TODO:

  • Update README

  • Add missing Clang versions

  • Refer to the issue that supports this Pull Request.

  • If the issue has missing info, explain the purpose/use case/pain/need that covers this Pull Request.

  • I've read the Contributing guide.

  • I've followed the PEP8 style guides for Python code.

  • I've followed the Best Practices guides for Dockerfile.

Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
@uilianries uilianries changed the title Add CCI images [WIP] Add CCI images May 22, 2020
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
@uilianries uilianries force-pushed the feature/base-image branch from 6cf1c14 to e70e1b4 Compare May 22, 2020 20:35
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
@Croydon
Copy link
Contributor

Croydon commented May 23, 2020

I don't understand. What is the purpose of those images?

@uilianries
Copy link
Member Author

Same base image, same glic version. We will keep the same image for all builds on CCI, well, not all builds as you can see. Of course, it will require rebuilding a lot packages there, but that's a not a problem.

Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
Signed-off-by: Uilian Ries <[email protected]>
@uilianries uilianries marked this pull request as draft June 3, 2020 22:27
@uilianries uilianries changed the title [WIP] Add CCI images Add CCI images Jun 3, 2020
@uilianries uilianries changed the title Add CCI images Use base image for all compiler version Jun 4, 2020
@Croydon
Copy link
Contributor

Croydon commented Jun 9, 2020

Using Ubuntu Xenial for all containers means

  • using glibc 2.23
  • this keeps or downgrades the glibc versions for all compiler versions except the GCC < 5 containers
  • supports (obviously) Ubuntu Xenial and newer
  • supports RHEL 8 / CentOS 8 which has glibc version 2.28
  • packages won't work for RHEL 7 / CentOS 7 (glibc 2.17) and RHEL 6 / CentOS 6 (glibc 2.12)
  • supports Fedora > 24
  • support OpenSuse > 15

I think that it would have been nice having RHEL 7 / CentOS supported too, however, the default GCC versions there is GCC 4.8 and we don't build packages for this version anyway... so it should be fine.

I support this change 👍

By the way, https://distrowatch.com/table.php?distribution=ubuntu is nice to look thinks up like this 😄


When we already introducing such breaking changes we probably should talk about a few other things.

Like what happens when Conan 2.0 gets released will we just pull them into the containers and we potentially breaking people again or should there be specifically Conan 2.0 images? I think we should talk about this now, because we could potentially introduce a naming change right now to not break people with this current change

A random idea would be a naming schema like
conanio/<compiler>-<version>-conan1 and then later conanio/<compiler>-<version>-conan2

If we use this naming schema now the already existing images could be continued to be used as-is without a change in distro version and glibc version.

@Croydon
Copy link
Contributor

Croydon commented Jun 9, 2020

@uilianries Did I understand it correctly that the GCC image won't work for GCC < 6? Why not?

@uilianries
Copy link
Member Author

@Croydon perfect!!!

A random idea would be a naming schema like
conanio/--conan1 and then later conanio/--conan2

As you know, we use the Conan version as docker tag. For those new images I thought conanio/-cci, but it's a suggestion.

Indeed Conan 2.0 will be a good opportunity for breaking changes, including for docker images if needed.

@uilianries uilianries mentioned this pull request Jun 16, 2020
5 tasks
Comment on lines +21 to +40
libc6-dev \
gcc \
libgmp-dev \
libmpfr-dev \
libmpc-dev \
nasm \
dh-autoreconf \
libffi-dev \
libssl-dev \
pkg-config \
subversion \
zlib1g-dev \
libbz2-dev \
libsqlite3-dev \
libreadline-dev \
xz-utils \
curl \
libncurses5-dev \
libncursesw5-dev \
liblzma-dev \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the devpackages and other utils be removed at the end of the docker script?
Keeping only the runtime libraries reduces size and avoids accidental dependencies on system libraries.
I assume keeping only the regular packages will keep everything working?

cci recipes should use the packages provided by cci.
e.g. libgmp, libmpfr, libmpc, nasm, autoconf, zlib, 'libbz2', sqlite3, ncurses, flex, xz-utils, ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of them, yes. We need to filter it, but it's an excellent idea.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. libc6-dev should be kept installed, as probably pkg-config, git, subversion...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know some packages were installed to build python, libsqlite3-dev for instance, so you are right. I'll comb through the packages and check what can removed. As the images have unit tests, it's possible to see what breaks after removing a system package.

Copy link
Contributor

@madebr madebr Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What makes this hard is that e.g. libsqlite3-dev should be removed, but libsqlite3 should be kept installed.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if you install everything into usr/local won't it make sense to start "final" image from scratch and just copy this whole directory into the new one? So whatever is needed to build gcc stays in the "build" image?

@madebr
Copy link
Contributor

madebr commented Jun 21, 2020

I have a radical idea: use conan for building these extra packages.

So what I am proposing is the following:

Create cpython, gcc, ... recipes that: named e.g. cpython/3.8.3@cci-ci/system, gcc/10.1@cci-ci/system

  1. use -dev system packages for building the package
  2. use regular (without -dev) system packages when consuming the package

Create a docker recipe that can build and upload the cpython/gcc conan packages.

  1. This docker image will thus have installed the -dev system packages.
  2. This docker image should only be built once for each conan recipe. Or once if you re-use it for all conan recipes.
  3. These images should upload the conan packages somewhere.

Create a consumer docker image that will do the ci:

  1. These should have installed the bare minimum: glibc-devel + .. ?
  2. These should install the conan gcc and python packages.
  3. Use profiles to build the recipes.

The docker images will probably have a bootstrap problem, because the default python version is too old, but I think this is solvable:

  1. Download and verify the raw tarball cpython/3.8.3@cci-ci/system (without conan/cpython because the default python version might be too old)
  2. Extract it + modify the PATH variables
  3. By writing cpython/3.8.3@cci-ci/system in such way that they are easy consumable without conan (e.g. by adding a .sh script that will set the paths correct)

Pros of this approach:

  • Never serve food you wouldn't eat yourself: conan is a package manager. So use it.
  • This would also avoid having to rebuild e.g. cpython for all the docker image combinations for e.g. a minor build script fix. All docker images should be rebuilt, but they should only download + extract the newer conan cpython package. Same goes for gcc/llvm.
  • The build environment is easier to reproduce by users without having to use docker.

Cons:

  • Not a standard build configuration, so bugs might appear.
    This is not really a con, because conan should fix these.
  • Not a pure docker image, because docker+conan.

@ytimenkov
Copy link

Not that radical. It's even documented on doc.conan.io. 😂 and we use it for couple years at work.
But I do agree: since you started building compiler yourself why not just it as a package?

@dheater
Copy link

dheater commented Jul 23, 2020

Using Ubuntu Xenial for all containers means

* using glibc 2.23 
* this keeps or downgrades the glibc versions for all compiler versions except the GCC < 5 containers
* supports (obviously) Ubuntu Xenial and newer
* supports RHEL 8 / CentOS 8 which has glibc version 2.28
* packages won't work for RHEL 7 / CentOS 7 (glibc 2.17) and RHEL 6 / CentOS 6 (glibc 2.12)
* supports Fedora > 24
* support OpenSuse > 15

I think that it would have been nice having RHEL 7 / CentOS supported too, however, the default GCC versions there is GCC 4.8 and we don't build packages for this version anyway... so it should be fine.

Older glibc can be used with newer compilers. The conanio/gcc7-centos6 image has gcc7 with glibc 2.12

From my selfish perspective, my current product is supporting RHEL 6 and 7 until their end of maintenance support 2:
For RHEL 7 that's June 30, 2024.
For REHL 6 that is November 30, 2020 and we've been asked by customers to continue for at least another year afterward.
https://access.redhat.com/support/policy/updates/errata/

I understand not wanting to maintain such old versions in conan.io.
I'd just like to keep a path for those of use with long-term support requirements to continue using conan (built and maintained locally if needed). I'm willing to help on that front.

@dheater
Copy link

dheater commented Jul 23, 2020

For conan 2 would there be a way to encode the supported glibc and request a no newer than version? The problem I often run into is that builds try to use binary packages built against newer glibc versions than my platform supports.

@ohanar
Copy link

ohanar commented Jul 31, 2020

@dheater I'm in a similar boat as you -- Ubuntu LTS 8 year maintenance is too short for the 10+ year maintenance of RHEL and SLES used by enterprises.

@ohanar
Copy link

ohanar commented Jul 31, 2020

I think that it would have been nice having RHEL 7 / CentOS supported too, however, the default GCC versions there is GCC 4.8 and we don't build packages for this version anyway... so it should be fine.

I'm going to guess most developers who have to continue supporting these platforms are using Redhat's Devtoolset, which means that in practice they are using new compilers (e.g. gcc 8 on RHEL/CentOS 6 and presently gcc 9 for RHEL/CentOS 7).

@Croydon
Copy link
Contributor

Croydon commented Aug 18, 2020

In order to use CentOS as a base, we would need to be able to have their all major version of GCC 4.9+ and Clang 3.9+

Do you see any way to do this?

@ohanar
Copy link

ohanar commented Aug 18, 2020

@Croydon For gcc there have been developer toolsets:
devtoolset-3 -- gcc 4.9.x
devtoolset-4 -- gcc 5.x
devtoolset-6 -- gcc 6.x
devtoolset-7 -- gcc 7.x
devtoolset-8 -- gcc 8.x
devtoolset-9 -- gcc 9.x

That said, they aren't available immediately upon the release of a new version of the compiler (e.g. no devtoolset-10 yet), and the old ones have been taken off of the repos as they have been EOLed. Currently, only devtoolset 7-9 are available. There are also llvm-toolsets for clang, however, I'm not as familiar with them.

The fundamental difference between these toolsets, and just compiling gcc and/or clang yourself on CentOS is that they have a mixed linking model with libstdc++. By default, the devtoolset will dynamically link in symbols that exist in gcc-4.8.5's version of libstdc++, and will statically link in anything from a newer gcc's version, and for the same reason, they always use the old gcc abi (i.e. trying to force the new gcc abi does nothing).

The most portable option for C++ is to just statically link against libstdc++/libc++, as there is no real telling what version of the library will be on the host system. Given that, I think probably the best bet would to just build the compilers oneself, probably using a relatively recent devtoolset for the bootstrapping process.

@ytimenkov
Copy link

The fundamental difference between these toolsets, and just compiling gcc and/or clang yourself on CentOS is that they have a mixed linking model with libstdc++

I'm currently trying to do the same thing at work. Looking at RedHat's spec (and patches) for gcc makes me cry: libstdc++-compat patch is 12 thousands lines long and basically adds a lot of files into a static library.

There are actually 2 libraries involved: libgcc_s and libstdc++. The former is required to propagate exceptions properly through shared libraries' boundaries and even gcc has it as a linker script (with system-wide shared library first and fall back to a static one to fill the gaps).

However libstdc++ seems to be trickier to handle with respect to binary compatibility, and I agree that linking it statically is probably the best option for portability. It is also different for static / shared libraries (ones which are Conan packages): the latter ones already have undefined (or defined) symbols...

Croydon added a commit to bincrafters/bincrafters-package-tools that referenced this pull request Dec 14, 2020

FROM base as release

RUN pip install -U conan conan-package-tools

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
RUN pip install -U conan conan-package-tools
RUN pip install -U conan conan-package-tools

liblzma-dev \
ca-certificates \
autoconf-archive \
flex \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you planning to pin the versions of those packages?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, pinning versions on Ubuntu is useless, as it doesn't keep old versions available for installation. We tried it in the past, but it caused us more problems than security and stability.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the attitude 👍 So no issues with reproducibility?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, you could create a builder/base image (and publish it for example to, say GitHub packages) and then only update compiler / conan.

@uilianries
Copy link
Member Author

Superseded by #271

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants