IBM Support

How to create binary blobs for Cloud Foundry on POWER8 Ubuntu LE

Technical Blog Post


Abstract

How to create binary blobs for Cloud Foundry on POWER8 Ubuntu LE

Body

I will be maintaining a set of instructions for creating binary blobs for POWER8 Ubuntu LE in this blog:

Name of the blob Filename Instructions
power DNS

 

pdns-static_3.3-1_ppc64el.deb

How to build deb:

Make sure you have gcc <= 5.0 ( $ gcc --version )

$ sudo apt-get install libboost-all-dev

$ sudo apt-get install ragel

$ sudo apt-get install checkinstall

$ git clone https://github.com/PowerDNS/pdns.git

$ cd pdns

$ ./bootstrap

$ ./configure --with-modules="" (add modules you need)

$ make

$ sudo checkinstall

You should get something like pdns-static_3.3-1_ppc64el.deb

openjdk java-7-openjdk-ppc64el.tgz

apt-get install openjdk-7-jre

apt-get install openjdk-7-jdk

cd /usr/lib/jvm

tar -cf java-7-openjdk-ppc64el.tgz java-7-openjdk-ppc64el

mysql server-5.1.62-rel14.4-xxx-Linux-ppc64le.tar.gz

wget http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-5.1.62.tar.gz

FLAGS: http://dev.mysql.com/doc/refman/5.0/en/source-installation.html

CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors \
       -fno-exceptions -fno-rtti" ./configure \
       --prefix=/usr/local/mysql --enable-assembler \
       --with-mysqld-ldflags=-all-static

       --without-server # only when building the client package

make
make install
cd /usr/local/mysql

postgres postgres-9.0.3-1.ppc64le.tar.gz
postgresql-9.0.3.tar.gz

./configure CFLAGS="-O0"
make
make install
mkdir /usr/local/pgsql/datavcap
chown vcap /usr/local/pgsql/datavcap
su - vcap
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/datavcap
/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/datavcap > logfile 2>&1 &
/usr/local/pgsql/bin/createdb test
/usr/local/pgsql/bin/psql test

tar cvfz postgres-9.0.3-1.ppc64le.tar.gz *

 

tar xvfz postgresql-9.0.3.tar.gz ; cd postgresql-9.0.3
# download new versions of config.*
$ curl "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config…; > config.guess
cd ..
tar cvfz postgresql-9.0.3.tar.gz postgresql-9.0.3

redis redis-2.6.9.tar.gz

Download blob from Amazon S3 blobstore as part of bosh create release

tar xvfz redis-2.6.9.tar.gz
cd redis-2.6.9
# download new versions of config.*
$ curl "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config…; > config.guess
cd ..
tar cvfz redis-2.6.9.tar.gz redis-2.6.9

ruby ruby-2.1.4.tar.gz

Download blob from Amazon S3 blobstore as part of bosh create release

# create tmp folder for update
bosh$ mkdir ../packages
$ cd packages

# download new versions of config.*
$ curl "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config…; > config.guess
$ curl "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config…; > config.sub


$ tar zxvf ruby-2.1.4.tar.gz
# find wher config files are located
$find ruby-2.1.4/ -name config.guess
# update config files
$ cp config.* ruby-2.1.4/config/
# remove old package (optional)
$ tar cvfz ruby-2.1.4.tar.gz ruby-2.1.4/

 

yaml

yaml-0.1.5.tar.gz

yaml-0.1.6.tar.gz

Download blob from Amazon S3 blobstore as part of bosh create release

releases for ruby/yaml, postgres and redis:

# create tmp folder for update
bosh$ mkdir ../packages
$ cd packages

# download new versions of config.*
$ curl "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config…; > config.guess
$ curl "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config…; > config.sub

#### -  repeat steps for [yaml, postgres, redis]:
# find package location
$ find ../bosh/release/blobs -name "yaml*"
# copy to tmp dir
$ cp ../bosh/release/blobs/ruby/yaml-0.1.5.tar.gz .
# extract package
$ tar zxvf yaml-0.1.5.tar.gz
# find wher config files are located
$find yaml-0.1.5/ -name config.guess
    -> yaml-0.1.5/config/config.guess
# update config files
$ cp config.* yaml-0.1.5/config/
# remove old package (optional)
$ rm -f yaml-0.1.5.tar.gz
# create new package
$ tar czf yaml-0.1.5.tar.gz yaml-0.1.5/
# update release
$ cp  yaml-0.1.5.tar.gz ../bosh/release/blobs/ruby/

 

gccgo_ppc64le_trusty gccgo.tar.bz2

For gccgo 1.3 use instructions from: https://www.ibm.com/developerworks/library/d-docker-on-power-linux-platform/#1.4.4.Buildinggccgo

For gccgo 1.4

Note: patching is not necessary for go 1.4.2+

Instal prereqs:

$ sudo apt-get install -y build-essential libgmp-dev libgmp3-dev libmpfr-dev libmpc-dev flex subversion
$ sudo apt-get install -y git mercurial libsqlite3-dev lxc libffi-dev pandoc ruby ruby-dev curl
$ sudo apt-get install -y aufs-tools btrfs-tools libdevmapper-dev libapparmor-dev
$ sudo apt-get install -y linux-image-extra-`uname -r`
$ sudo gem install fpm

Build gccgo:

$ mkdir ~/gccgo
$ cd ~/gccgo
$ svn co svn://gcc.gnu.org/svn/gcc/branches/gcc-5-branch src
$ mkdir bld
$ cd bld

On POWER8:

$ ../src/configure --enable-threads=posix --enable-shared --enable-__cxa_atexit \
    --enable-languages=c,c++,go --enable-secureplt --enable-checking=yes --with-long-double-128 \
    --enable-decimal-float --disable-bootstrap --disable-alsa --disable-multilib \
    --prefix=/usr/local/gccgo

On POWER7 the only difference is  --with-cpu=power7:

../src/configure --enable-threads=posix --enable-shared --enable-__cxa_atexit \
    --enable-languages=c,c++,go --enable-secureplt --enable-checking=yes --with-long-double-128 \
    --enable-decimal-float --disable-bootstrap --disable-alsa --disable-multilib \
    --prefix=/usr/local/gccgo  --with-cpu=power7

$ make
$ sudo make install

rootfs rootfsppc64.tgz

 1. in a ppc64le machine git clone https://github.com/cloudfoundry/warden.git

2. Put two scripts (build.sh and helpers.sh) in warden/warden and execute
see bottom of this page for the contents of build.sh and helpers.sh

dea_next_gems dea_next_gems_vendor_cache.tar.gz which includes: eventmachine-1.0.3.gem, nokogiri-1.6.3.1.gem, nokogiri-1.6.6.2.gem, nokogiri-1.6.2.1.gem, ffi-1.9.3.gem,

This blob includes ruby gems that failed to install using the gem install command on ppc64le: nokogiri-xxx.gem, ffi. and eventmachine-xxx.gem

Below are steps to recreate the gems from source with minor tweaks to enable installation on ppc64le:

1. Install vagrant

2. Download the rake compiler devbox on your laptop: git clone https://github.com/tjschuck/rake-compiler-dev-box.git

3. vagrant up

4. vagrant ssh

5. install rvm: https://rvm.io/rvm/install

6. rvm install 1.9.2 and rvm install 2.1.2

7. rvm use 1.9.2

8. git clone https://github.com/sparklemotion/nokogiri.git and cd nokogiri

9. git checkout <version tag e.g. v1.6.2.1>

10. vi ext/nokogiri/extconf.rb

11. search for libxml2_recipe and libxslt_recipe

12. Replace links to libxml2-xx.tar.gz and libxslt-xx.tar.gz

    recipe.files = ["http://ausgsa.ibm.com/projects/s/stai/powerbluemix/#{recipe.name}-#{recipe.version}.tar.gz"]

    recipe.files = ["http://ausgsa.ibm.com/projects/s/stai/powerbluemix/#{recipe.name}-#{recipe.version}.tar.gz"]

13. Download ftp://ftp.xmlsoft.org/libxml2/libxml2-2.8.0.tar.gz

14. Download ftp://ftp.xmlsoft.org/libxml2/libxslt-1.1.28.tar.gz

15. Untar source: tar xvfz

16. #download new versions of config.*
$ curl "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config…; > config.guess

17. update config.guess files and tar cfvz

18. Upload tar files to link used in step 12.

19. run gem install bundler

20. run bundle install

21. run rake gem or rake gem:package

22. the new gem is in the folder pkg

 

For eventmachine-xx.gem

1.  git clone https://github.com/eventmachine/eventmachine.git and cd eventmachine

2. git checkout <version tag e.g. v0.12.10 git tag to find other versions>

3. vi ext/rubymain.cpp

4. on line 468 and 488, add '"%s",' before e.what():

-               rb_raise (EM_eConnectionError, e.what());
+               rb_raise (EM_eConnectionError, "%s", e.what());

5.gem build eventmachine.gemspec

6. the new gem is in the pkg directory

 

For ffi-xx.gem

1. rvm use 2.1.2

2. git clone https://github.com/ffi/ffi.git and cd ffi

3. git checkout <version tag e.g. v1.9.3>

4. cd cd ext/ffi_c/

5. rm -rf libffi

6. git clone https://github.com/atgreen/libffi.git (latest version of libffi sourc)

7. make these changes:

--- a/Rakefile
+++ b/Rakefile
@@ -36,6 +36,10 @@ CPU = case RbConfig::CONFIG['host_cpu'].downcase
   when /amd64|x86_64/
     "x86_64"

+  when /powerpc64le/
+    "ppc64le"
+
+
   when /ppc64|powerpc64/
     "powerpc64"

+++ b/ext/ffi_c/libffi.gnu.mk
@@ -20,6 +20,7 @@ else
 endif

 LIBFFI = "$(LIBFFI_BUILD_DIR)"/.libs/libffi_convenience.a
+LIBFFI_AUTOGEN = "$(LIBFFI_SRC_DIR)"/autogen.sh
 LIBFFI_CONFIGURE = "$(LIBFFI_SRC_DIR)"/configure --disable-static \
        --with-pic=yes --disable-dependency-tracking

@@ -4,6 +4,10 @@ include ${srcdir}/libffi.gnu.mk

 $(LIBFFI):
        @mkdir -p "$(LIBFFI_BUILD_DIR)" "$@(D)"
+       @if [ ! -f "$(LIBFFI_SRC_DIR)"/configure ]; then \
+           echo "Running autogen libffi"; \
+           cd "$(LIBFFI_SRC_DIR)" && $(LIBFFI_AUTOGEN); \
+       fi
        @if [ ! -f "$(LIBFFI_BUILD_DIR)"/Makefile ]; then \
            echo "Configuring libffi"; \
            cd "$(LIBFFI_BUILD_DIR)" && \

 

for version 1.9.8, the diffs were as follows:

diff --git a/Rakefile b/Rakefile

index 3aa7a75..fd40075 100644

--- a/Rakefile

+++ b/Rakefile

@@ -34,6 +34,9 @@ CPU = case RbConfig::CONFIG['host_cpu'].downcase

when /amd64|x86_64/

"x86_64"

+ when /powerpc64le/

+ "ppc64le"

+

when /ppc64|powerpc64/

"powerpc64"

diff --git a/ext/ffi_c/libffi.gnu.mk b/ext/ffi_c/libffi.gnu.mk

index 2af7a75..f56abd1 100644

--- a/ext/ffi_c/libffi.gnu.mk

+++ b/ext/ffi_c/libffi.gnu.mk

@@ -20,6 +20,7 @@ else

endif

LIBFFI = "$(LIBFFI_BUILD_DIR)"/.libs/libffi_convenience.a

+LIBFFI_AUTOGEN = "$(LIBFFI_SRC_DIR)"/autogen.sh

LIBFFI_CONFIGURE = "$(LIBFFI_SRC_DIR)"/configure --disable-static \

--with-pic=yes --disable-dependency-tracking

diff --git a/ext/ffi_c/libffi.mk b/ext/ffi_c/libffi.mk

index 85c15c5..1d155d8 100644

--- a/ext/ffi_c/libffi.mk

+++ b/ext/ffi_c/libffi.mk

@@ -4,6 +4,10 @@ include ${srcdir}/libffi.gnu.mk

$(LIBFFI):

@mkdir -p "$(LIBFFI_BUILD_DIR)" "$@(D)"

+ @if [ ! -f "$(LIBFFI_SRC_DIR)"/configure ]; then \

+ echo "Running autogen libffi"; \

+ cd "$(LIBFFI_SRC_DIR)" && $(LIBFFI_AUTOGEN); \

+ fi

@if [ ! -f "$(LIBFFI_BUILD_DIR)"/Makefile ]; then \

echo "Configuring libffi"; \

cd "$(LIBFFI_BUILD_DIR)" && \

8. run rake gem, the new gem will be in subdirectory pkg

 

After all the modified gems are built, put them into two level sub-directory called vendor/cache and tar up the gems into a file: dea_next_gems_vendor_cache.tar.gz

root@bluemix-bootstrap:/work4/cf-release/blobs/dea_next_gems# tar tvfz dea_next_gems_vendor_cache.tar.gz
drwxr-xr-x root/root         0 2015-04-17 08:34 vendor/
drwxr-xr-x root/root         0 2015-04-17 08:34 vendor/cache/
-rw-r--r-- root/root    225792 2014-08-26 12:41 vendor/cache/eventmachine-1.0.3.gem
-rw-r--r-- root/root   8907264 2014-08-26 12:44 vendor/cache/nokogiri-1.6.3.1.gem
-rw-r--r-- root/root   1639936 2014-08-26 12:41 vendor/cache/ffi-1.9.3.gem
-rw-r--r-- root/root    454144 2015-02-11 03:46 vendor/cache/nokogiri-1.6.2.1.gem

 

 

 

 


build.sh

 


#!/bin/bash

set -e -x

source ./helpers.sh

base_dir=$(pwd)
assets_dir=$base_dir/assets
rootfs_dir=/tmp/warden/rootfs

function apt_get {
  run_in_chroot $rootfs_dir "apt-get update"
  run_in_chroot $rootfs_dir "apt-get -f -y --force-yes --no-install-recommends $*"
  run_in_chroot $rootfs_dir "apt-get clean"
}

packages="
  bind9-host
  bison
  build-essential
  curl
  dnsutils
  flex
  gdb
  git
#  imagemagick
  iputils-arping
  libaio1
  libbz2-dev
  libcap2-bin
  libcurl3
  libcurl3-dev
#  libmagick9-dev
  libmysqlclient-dev
  libncurses5-dev
  libpq-dev
  libreadline6-dev
  libsqlite-dev
  libsqlite3-dev
  libssl-dev
  libxml2
  libxml2-dev
  libxslt1-dev
  libxslt1.1
  libyaml-dev
  lsof
  openssh-server
  psmisc
  quota
  rsync
  strace
  sysstat
  tcpdump
  traceroute
  unzip
  wget
  zip
"

# setup warden's default rootfs
(
#  cd /warden/warden
  bundle install && bundle exec rake setup[config/linux.yml]
)

# source /etc/lsb-release if present
if [ -f $rootfs_dir/etc/lsb-release ]
then
  source $rootfs_dir/etc/lsb-release
fi

# disable interactive dpkg
debconf="debconf debconf/frontend select noninteractive"
run_in_chroot $rootfs_dir "echo ${debconf} | debconf-set-selections"

# networking
cp $assets_dir/etc/hosts $rootfs_dir/etc/hosts

# timezone
cp $assets_dir/etc/timezone $rootfs_dir/etc/timezone
run_in_chroot $rootfs_dir "dpkg-reconfigure -fnoninteractive -pcritical tzdata"

# locale
cp $assets_dir/etc/default/locale $rootfs_dir/etc/default/locale
run_in_chroot $rootfs_dir "
locale-gen en_US.UTF-8
dpkg-reconfigure -fnoninteractive -pcritical libc6
dpkg-reconfigure -fnoninteractive -pcritical locales
"

# firstboot script
cp $assets_dir/etc/rc.local $rootfs_dir/etc/rc.local
cp $assets_dir/root/firstboot.sh $rootfs_dir/root/firstboot.sh
chmod 0755 $rootfs_dir/root/firstboot.sh

# apt sources
#cat > $rootfs_dir/etc/apt/sources.list <<EOS
#deb http://archive.ubuntu.com/ubuntu $DISTRIB_CODENAME main universe multiverse
#deb http://archive.ubuntu.com/ubuntu $DISTRIB_CODENAME-updates main universe multiverse
#deb http://security.ubuntu.com/ubuntu $DISTRIB_CODENAME-security main universe multiverse
#deb http://ppa.launchpad.net/git-core/ppa/ubuntu $DISTRIB_CODENAME main
#EOS

# upgrade upstart first to prevent it from messing up our stubs and starting daemons anyway
apt_get install upstart
apt_get dist-upgrade
apt_get install $packages

# install ruby using ruby-build
#run_in_chroot $rootfs_dir "
#  cd /tmp &&
#  git clone git://github.com/sstephenson/ruby-build.git &&
#  cd ruby-build &&
#  PREFIX=/usr/local ./install.sh &&
#  /usr/local/bin/ruby-build 1.9.3-p392 /usr
#"

# package up rootfs
#cd $rootfs_dir
#tar czf /vagrant/rootfs.tgz *


helpers.sh



function disable {
  mv $1 $1.back
  ln -s /bin/true $1
}

function enable {
  if [ -L $1 ]
  then
    mv $1.back $1
  else
    # No longer a symbolic link, must have been overwritten
    rm -f $1.back
  fi
}

function run_in_chroot {
  local chroot=$1
  local script=$2

  # Disable daemon startup
  disable $chroot/sbin/initctl
  disable $chroot/usr/sbin/invoke-rc.d

  unshare -m $SHELL <<EOS
    mkdir -p $chroot/dev
    mount -n --bind /dev $chroot/dev
    mount -n --bind /dev/pts $chroot/dev/pts

    mkdir -p $chroot/proc
    mount -n -t proc proc $chroot/proc

    chroot $chroot env -i $(cat $chroot/etc/environment) http_proxy=${http_proxy:-} bash -e -c "$script"
EOS

  # Enable daemon startup
  enable $chroot/sbin/initctl
  enable $chroot/usr/sbin/invoke-rc.d
}
 

Comments and questions are welcome!!

[{"Business Unit":{"code":"BU054","label":"Systems w\/TPS"},"Product":{"code":"HW1W1","label":"Power ->PowerLinux"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"","label":""}}]

UID

ibm16170517