set -eu

# We need to perform some linker tomfoolery in order to successfully compile
# runc for running on a BOSH VM. runc systemd support requires dynamic linking.
#
# We could modify the dynamic linker path settings of the machine as a whole or
# add our libraries to the machine's pool. We're not ok with this because this
# will interfere with other jobs on the machine which is unacceptable.
#
# Typically, you can set the LD_LIBRARY_PATH environment variable which will
# modify the linker's search path in any programs which have that environment
# variable present. Unfortunately this does not work in this case because runc
# re-execs itself with an empty environment which causes the child process to
# crash because it cannot find the libraries to link against.
#
# Instead we add an attribute in the binary to tell the linker where to find
# libraries whenever this binary is executed. We feel this is acceptable
# because we have such tight control over the execution environment in our
# deployments.
#
# The path we set is different from the current package path because we
# eventually move the binary and libraries before running them, as part of bpm
# packaging.
# 
# The runc Makefile has a parameter for modifying the linker options but it is
# broken in the case that Git is not installed on the system because of quoting
# mishaps.

RUNC_VERSION=1.0.0-rc9

PKG_CONFIG_VERSION=0.29.2
PKG_CONFIG_PREFIX="$(mktemp -d)"

LIBSECCOMP_PREFIX="${BOSH_INSTALL_TARGET}/lib/libseccomp"
LIBSECCOMP_RUNTIME_PATH=/var/vcap/packages/bpm/lib/libseccomp/lib
LIBSECCOMP_VERSION=2.4.2

RUNC_PACKAGE_PATH=github.com/opencontainers/runc

# compile pkg-config
(
  set -eu

  tar xzf "pkg-config/pkg-config-${PKG_CONFIG_VERSION}.tar.gz"
  cd "pkg-config-${PKG_CONFIG_VERSION}"
  ./configure --prefix="${PKG_CONFIG_PREFIX}" --with-internal-glib
  make
  make install prefix="${PKG_CONFIG_PREFIX}"
)

# compile libseccomp
(
  set -eu

  tar zxf "libseccomp/libseccomp-${LIBSECCOMP_VERSION}.tar.gz"
  cd "libseccomp-${LIBSECCOMP_VERSION}"
  ./configure --prefix="${LIBSECCOMP_PREFIX}"
  make
  make install
)

# install runc
(
  set -eu
  export PATH="${PKG_CONFIG_PREFIX}/bin:$PATH"

  export GOROOT=$(readlink -nf /var/vcap/packages/golang)
  export PATH=${GOROOT}/bin:${PATH}
  export GOPATH="${BOSH_INSTALL_TARGET}"

  mkdir -p "${BOSH_INSTALL_TARGET}/src/$RUNC_PACKAGE_PATH"
  tar xzf "runc/runc-${RUNC_VERSION}.tar.gz" -C "${BOSH_INSTALL_TARGET}/src/${RUNC_PACKAGE_PATH}" --strip-components 1
  (
    set -eu
    env \
          GOCACHE="${BOSH_INSTALL_TARGET}/cache" \
          PKG_CONFIG_PATH="${LIBSECCOMP_PREFIX}/lib/pkgconfig" \
          go build \
            -buildmode=pie \
            -ldflags "-X main.gitCommit=unknown -X main.version=${RUNC_VERSION}-bpm -r ${LIBSECCOMP_RUNTIME_PATH}" \
            -tags "seccomp apparmor" \
            -o "${BOSH_INSTALL_TARGET}/bin/runc" \
            "${RUNC_PACKAGE_PATH}"
  )
)

# clean up source artifacts
rm -r "${BOSH_INSTALL_TARGET}/src"
rm -r "${BOSH_INSTALL_TARGET}/cache"
rm -r "${PKG_CONFIG_PREFIX}"
