Commit ef97de7d authored by Tim Schoof's avatar Tim Schoof
Browse files

Initial commit

COPY /build_scripts/
RUN bash build_scripts/ && rm -r build_scripts
\ No newline at end of file
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# Every Vagrant development environment requires a box. You can search for
# boxes at = "centos/7"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# "forwarded_port", guest: 80, host: 8080
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via to disable public access
# "forwarded_port", guest: 80, host: 8080, host_ip: ""
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# "private_network", ip: ""
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/data"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
# View the documentation for the provider you are using for more
# information on available options.
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
yum install -y yum-utils
yum-config-manager \
--add-repo \
yum install -y docker-ce docker-ce-cli
systemctl enable --now docker
usermod -aG docker vagrant
docker build -t ${NAME} .
if [[ $1 == "push" ]]; then
docker push ${NAME}
# freezing requires that python was built with --shared-enabled
# Otherwise the built closely follows the steps from the manylinux1 build
# Stop at any error, show all commands
set -ex
MY_DIR=$(dirname "${BASH_SOURCE[0]}")
# download the required files from the manylinux repository
mkdir -p build_scripts
pushd build_scripts
curl -fsSLO
curl -fsSLO
curl -fsSLO
curl -fsSLO
curl -fsSLO
curl -fsSLO
source build_scripts/
# overwrite, as we only need a few python versions
# of the form <maj>.<min>.<rev> or <maj>.<min>.<rev>rc<n>
# Dependencies for compiling Python that we want to remove from
# the final image after compiling Python
# GPG installed to verify signatures on Python source tarballs.
PYTHON_COMPILE_DEPS="zlib-devel bzip2-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel gpg libffi-devel"
# the following definitions are copied from
# with minor adaptions for python builds with --enable-shared
function check_var {
if [ -z "$1" ]; then
echo "required variable not defined"
exit 1
function lex_pyver {
# Echoes Python version string padded with zeros
# Thus:
# 3.2.1 -> 003002001
# 3 -> 003000000
echo $1 | awk -F "." '{printf "%03d%03d%03d", $1, $2, $3}'
function pyver_dist_dir {
# Echoes the dist directory name of given pyver, removing alpha/beta prerelease
# Thus:
# 3.2.1 -> 3.2.1
# 3.7.0b4 -> 3.7.0
echo $1 | awk -F "." '{printf "%d.%d.%d", $1, $2, $3}'
function do_cpython_build {
local py_ver=$1
check_var $py_ver
local ucs_setting=$2
check_var $ucs_setting
tar -xzf Python-$py_ver.tgz
pushd Python-$py_ver
if [ "$ucs_setting" = "none" ]; then
local unicode_flags="--enable-unicode=$ucs_setting"
local dir_suffix="-$ucs_setting"
local prefix="/opt/_internal/cpython-${py_ver}${dir_suffix}"
mkdir -p ${prefix}/lib
# BEGIN CHANGE for shared build
# ./configure --prefix=${prefix} --disable-shared $unicode_flags > /dev/null
./configure --prefix=${prefix} --enable-shared $unicode_flags > /dev/null
make -j2 > /dev/null
make install > /dev/null
rm -rf Python-$py_ver
# BEGIN CHANGE for shared build
# symlink shared library
for path in ${prefix}/lib/libpython*; do
ln -s $path /usr/lib64/$(basename $path)
# Some python's install as bin/python3. Make them available as
# bin/python.
if [ -e ${prefix}/bin/python3 ]; then
ln -s python3 ${prefix}/bin/python
${prefix}/bin/python -m ensurepip
if [ -e ${prefix}/bin/pip3 ] && [ ! -e ${prefix}/bin/pip ]; then
ln -s pip3 ${prefix}/bin/pip
# Since we fall back on a canned copy of pip, we might not have
# the latest pip and friends. Upgrade them to make sure.
if [ "${py_ver:0:1}" == "2" ]; then
${prefix}/bin/pip install -U --require-hashes -r ${MY_DIR}/py27-requirements.txt
${prefix}/bin/pip install -U --require-hashes -r ${MY_DIR}/requirements.txt
local abi_tag=$(${prefix}/bin/python ${MY_DIR}/
ln -s ${prefix} /opt/python/${abi_tag}
function build_cpython {
local py_ver=$1
check_var $py_ver
local py_dist_dir=$(pyver_dist_dir $py_ver)
curl -fsSLO $PYTHON_DOWNLOAD_URL/$py_dist_dir/Python-$py_ver.tgz
curl -fsSLO $PYTHON_DOWNLOAD_URL/$py_dist_dir/Python-$py_ver.tgz.asc
gpg --verify Python-$py_ver.tgz.asc
if [ $(lex_pyver $py_ver) -lt $(lex_pyver 3.3) ]; then
# BEGIN CHANGE for shared build
# we only need the wide unicode version
# do_cpython_build $py_ver ucs2
do_cpython_build $py_ver ucs4
do_cpython_build $py_ver none
rm -f Python-$py_ver.tgz
rm -f Python-$py_ver.tgz.asc
function build_cpythons {
# Import public keys used to verify downloaded Python source tarballs.
gpg --import ${MY_DIR}/cpython-pubkeys.txt
# Add version 3.8, 3.9 release manager's key
gpg --import ${MY_DIR}/ambv-pubkey.txt
for py_ver in $@; do
build_cpython $py_ver
# Remove GPG hidden directory.
rm -rf /root/.gnupg/
function do_perl_build {
sh Configure -des -Dprefix=/opt/perl > /dev/null
make > /dev/null
make install > /dev/null
function do_openssl_build {
./config no-shared -fPIC --prefix=/usr/local/ssl > /dev/null
make > /dev/null
make install_sw > /dev/null
function fetch_source {
# This is called both inside and outside the build context (e.g. in Travis) to prefetch
# source tarballs, where curl exists (and works)
local file=$1
check_var ${file}
local url=$2
check_var ${url}
if [ -f ${file} ]; then
echo "${file} exists, skipping fetch"
curl -fsSL -o ${file} ${url}/${file}
function check_sha256sum {
local fname=$1
check_var ${fname}
local sha256=$2
check_var ${sha256}
echo "${sha256} ${fname}" > ${fname}.sha256
sha256sum -c ${fname}.sha256
rm -f ${fname}.sha256
function build_perl {
local perl_fname=$1
check_var ${perl_fname}
local perl_sha256=$2
check_var ${perl_sha256}
# BEGIN CHANGE for shared build
# Can't use curl here because we don't have it yet, perl must be prefetched
# check_required_source ${perl_fname}.tar.gz
# Luckily, we do have curl here
fetch_source ${perl_fname}.tar.gz ${PERL_DOWNLOAD_URL}
check_sha256sum ${perl_fname}.tar.gz ${perl_sha256}
tar -xzf ${perl_fname}.tar.gz
(cd ${perl_fname} && do_perl_build)
rm -rf ${perl_fname} ${perl_fname}.tar.gz
function build_openssl {
local openssl_fname=$1
check_var ${openssl_fname}
local openssl_sha256=$2
check_var ${openssl_sha256}
fetch_source ${openssl_fname}.tar.gz ${OPENSSL_DOWNLOAD_URL}
check_sha256sum ${openssl_fname}.tar.gz ${openssl_sha256}
tar -xzf ${openssl_fname}.tar.gz
(cd ${openssl_fname} && PATH=/opt/perl/bin:$PATH do_openssl_build)
rm -rf ${openssl_fname} ${openssl_fname}.tar.gz
yum -y update
yum -y install gnupg ${PYTHON_COMPILE_DEPS}
# Build PERL in order to build OpenSSL. We'll delete this after OpenSSL build.
build_perl $PERL_ROOT $PERL_HASH
# Build an OpenSSL for Pythons. We'll delete this at the end.
# Delete PERL
rm -rf /opt/perl
# we don't need all the other python versions
# first save the certs
mv $(readlink -f /opt/_internal/certs.pem) /opt/_internal/certs.pem
# now delete the python directories
rm -rf /opt/_internal/cpython*
rm /opt/python/*
build_cpythons $CPYTHON_VERSIONS
# Now we can delete our built OpenSSL headers/static libs since we've linked everything we need
rm -rf /usr/local/ssl
yum -y erase gnupg ${PYTHON_COMPILE_DEPS} > /dev/null 2>&1
yum -y clean all > /dev/null 2>&1
yum list installed
\ No newline at end of file
vagrant rsync
vagrant ssh -c "
cd /vagrant \
&& docker build -t ${NAME} .
vagrant ssh -c "docker save ${NAME}" -- -T | docker load
if [[ $1 == "push" ]]; then
docker push ${NAME}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment