Skip to content

Instantly share code, notes, and snippets.

@StephanX
Last active February 25, 2019 00:17
Show Gist options
  • Save StephanX/5e0e319def4b838f0b9c7006c46703f5 to your computer and use it in GitHub Desktop.
Save StephanX/5e0e319def4b838f0b9c7006c46703f5 to your computer and use it in GitHub Desktop.
FROM python:3.6.4-slim-stretch
# Set up jenkins-slave & nodejs
# remoting changelog: https://github.com/jenkinsci/remoting/blob/master/CHANGELOG.md#315
ARG REMOTING_VERSION=3.15
ARG KUBE_VERSION=1.9.0
ARG NODEJS_VERSION=8
# Pay mind to https://launchpad.net/~webupd8team/+archive/ubuntu/java?field.series_filter= for the ubuntu java release and the java versions
ARG UBUNTU_JAVA_RELEASE=bionic
ARG EMBER_CLI_VERSION="2.13.2"
# ARG PYTHON_VERSION=3.6.4
# Java Version and other ENV
ENV JAVA_VERSION_MAJOR=8 \
JAVA_VERSION_MINOR=161 \
JAVA_VERSION_BUILD=12 \
JAVA_PACKAGE=jdk \
JAVA_JCE=unlimited \
JAVA_HOME=/usr/lib/jvm/java-8-oracle \
PATH=${PATH}:/opt/jdk/bin \
GLIBC_VERSION=2.23-r3 \
LANG=C.UTF-8
ENV HOME /root
ENV NPM_CONFIG_LOGLEVEL info
RUN apt-get update && apt-get -y upgrade \
&& apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
netcat \
gnupg2 \
software-properties-common \
lsb-release \
wget \
build-essential \
git \
openssh-client \
pwgen \
openssl \
less \
vim
# install Oracle Java
RUN mkdir -p /usr/share/man/man1 && \
echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && \
echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu ${UBUNTU_JAVA_RELEASE} main" | tee /etc/apt/sources.list.d/webupd8team-java.list && \
echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu ${UBUNTU_JAVA_RELEASE} main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && \
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && \
apt-get update && \
apt-get -y install oracle-java8-installer && \
rm -rf /var/cache/oracle-jdk8-installer && \
echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
# or if we want to switch to openjdk at some point
# RUN mkdir -p /usr/share/man/man1 && \
# apt-get update && \
# apt-get install -y default-jdk && \
# echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
# # Install python3.6
# RUN apt-get install -y \
# make \
# build-essential \
# libssl-dev \
# zlib1g-dev \
# libbz2-dev \
# libreadline-dev \
# libsqlite3-dev \
# wget \
# curl \
# llvm \
# libncurses5-dev \
# libncursesw5-dev \
# xz-utils \
# tk-dev \
# && cd /tmp \
# && wget https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz \
# && tar xvf Python-${PYTHON_VERSION}.tgz \
# && cd Python-${PYTHON_VERSION} \
# && ./configure --enable-optimizations \
# && make -j8 \
# && make altinstall \
# && ln -s /usr/local/bin/python3.6 /usr/local/bin/python3 \
# && ln -s /usr/local/bin/pip3.6 /usr/local/bin/pip3
# Install nodejs
RUN curl -sL https://deb.nodesource.com/setup_${NODEJS_VERSION}.x | bash - \
&& apt-get install -y nodejs
RUN npm install ember-cli@${EMBER_CLI_VERSION} gulp gulp-cli gulp-clone -g
RUN npm install bower -g
# Install MySQL
RUN set -ex; \
# gpg: key 5072E1F5: public key "MySQL Release Engineering <[email protected]>" imported
key='A4A9406876FCBD3C456770C88C718D3B5072E1F5'; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
gpg --export "$key" > /etc/apt/trusted.gpg.d/mysql.gpg; \
# rm -r "$GNUPGHOME"; \
apt-key list > /dev/null
# find this at http://repo.mysql.com/apt/debian/dists/stretch/mysql-5.7/binary-amd64/Packages
ENV MYSQL_MAJOR 5.7
# Will depend on what is located at http://repo.mysql.com/apt/debian/dists/stretch/mysql-5.7/binary-amd64/Packages
RUN echo "deb http://repo.mysql.com/apt/debian/ stretch mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list
# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)
# also, we set debconf keys to make APT a little quieter
RUN { \
echo mysql-community-server mysql-community-server/data-dir select ''; \
echo mysql-community-server mysql-community-server/root-pass password ''; \
echo mysql-community-server mysql-community-server/re-root-pass password ''; \
echo mysql-community-server mysql-community-server/remove-test-db select false; \
} | debconf-set-selections \
&& apt-get update && apt-get install -y mysql-server="$(curl -s http://repo.mysql.com/apt/debian/dists/stretch/mysql-${MYSQL_MAJOR}/binary-amd64/Packages | grep Version | awk '{ print $2 }' | sort -u | head -n 1)" \
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
&& chmod 777 /var/run/mysqld
RUN sed -Ei 's/^(bind-address|log)/#&/' /etc/mysql/mysql.conf.d/mysqld.cnf \
&& echo '[mysqld]\nskip-host-cache\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf \
&& echo '[mysqld]\nlower_case_table_names=1\nmax_allowed_packet=16M\nmax_connections=10000' > /etc/mysql/conf.d/iregretmylifedecisions.cnf
# Install Docker
RUN apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common \
&& curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | apt-key add - \
&& add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) \
stable" \
&& apt-get update \
&& apt-get install -y docker-ce
# Install everything else
RUN apt-get install -y \
redis-server
# Install Gradle
ENV GRADLE_HOME /opt/gradle
ENV GRADLE_VERSION 3.5
ARG GRADLE_DOWNLOAD_SHA256=0b7450798c190ff76b9f9a3d02e18b33d94553f708ebc08ebe09bdf99111d110
RUN apt-get install -y unzip \
\
&& echo "Downloading Gradle" \
&& wget -O gradle.zip "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" 2>&1 >>/dev/null \
\
&& echo "Checking download hash" \
&& echo "${GRADLE_DOWNLOAD_SHA256} *gradle.zip" | sha256sum -c - \
\
&& echo "Installing Gradle" \
&& unzip gradle.zip \
&& rm gradle.zip \
&& mkdir -p /opt \
&& mv "gradle-${GRADLE_VERSION}" "${GRADLE_HOME}/" \
&& ln -s "${GRADLE_HOME}/bin/gradle" /usr/bin/gradle
# python modules for kubernetes
RUN pip3 install kubernetes pyyaml Jinja2 awscli
# kubectl, helm, and jenkins slave jar
RUN curl --silent https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash
ADD https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/linux/amd64/kubectl /usr/local/bin/kubectl
ADD https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/${REMOTING_VERSION}/remoting-${REMOTING_VERSION}.jar /usr/share/jenkins/slave.jar
ADD https://github.com/rlmcpherson/s3gof3r/releases/download/v0.5.0/gof3r_0.5.0_linux_amd64.tar.gz /tmp
RUN chmod 755 /usr/local/bin/kubectl \
&& chmod 644 /usr/share/jenkins/slave.jar \
&& cd /tmp \
&& tar -xvf gof3r_0.5.0_linux_amd64.tar.gz \
&& mv gof3r_0.5.0_linux_amd64/gof3r /usr/local/bin/gofer \
&& chmod 0755 /usr/local/bin/gofer \
&& echo '{ "allow_root": true }' > /root/.bowerrc
# USER jenkins
RUN mkdir -p /root/.jenkins
VOLUME /root/.jenkins
WORKDIR /root
COPY jenkins-slave.sh /usr/local/bin/jenkins-slave.sh
RUN rm -rf /var/lib/apt/lists/* && \
rm -rf /tmp/*
ENTRYPOINT ["jenkins-slave.sh"]
=========================================
#jenkins-slave.sh
#!/usr/bin/env bash
# Usage jenkins-slave.sh [options] -url http://jenkins [SECRET] [AGENT_NAME]
# Optional environment variables :
# * JENKINS_TUNNEL : HOST:PORT for a tunnel to route TCP traffic to jenkins host, when jenkins can't be directly accessed over network
# * JENKINS_URL : alternate jenkins URL
# * JENKINS_SECRET : agent secret, if not set as an argument
# * JENKINS_AGENT_NAME : agent name, if not set as an argument
# Put our AWS credz in place
for i in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY ; do
export $i=$(< /root/.aws/$i)
done
# grab gradle
mkdir -p /root/.gradle && cd /root && gofer get -b squelch-devops -k gradle/gradle.tar.gz | tar -zx
# setup redis
echo "127.0.1.1 redis" >> /etc/hosts
redis-server --protected-mode no 2>&1 >> /var/log/redis.log &
# setup mysql
mkdir /run/mysqld
mysqld --initialize-insecure 2>&1 >> /var/log/mysql.log
mysqld --user=root 2>&1 >> /var/log/mysql.log &
echo "127.0.1.1 mysql" >> /etc/hosts
# hack to enable kubectl to use the config file local to it to talk to the api server. Needed to perform maintenance operations. This will not work, if kops starts assigning a different local IP for the api server.
echo "100.64.0.1 <YOUR K8s API SERVER GOES HERE>" >> /etc/hosts
while [[ ${res} != 0 ]] ; do
nc -z mysql 3306
res=$?
sleep 2
done
mysqladmin -u root password password
mysql -uroot -ppassword -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' IDENTIFIED BY PASSWORD '<YOUR SALTED PASSWORD>' WITH GRANT OPTION;"
if [ $# -eq 1 ]; then
# if `docker run` only has one arguments, we assume user is running alternate command like `bash` to inspect the image
exec "$@"
else
# start jenkins slave procs
# if -tunnel is not provided try env vars
if [[ "$@" != *"-tunnel "* ]]; then
if [ ! -z "$JENKINS_TUNNEL" ]; then
TUNNEL="-tunnel $JENKINS_TUNNEL"
fi
fi
if [ -n "$JENKINS_URL" ]; then
URL="-url $JENKINS_URL"
fi
if [ -n "$JENKINS_NAME" ]; then
JENKINS_AGENT_NAME="$JENKINS_NAME"
fi
if [ -z "$JNLP_PROTOCOL_OPTS" ]; then
echo "Warning: JnlpProtocol3 is disabled by default, use JNLP_PROTOCOL_OPTS to alter the behavior"
JNLP_PROTOCOL_OPTS="-Dorg.jenkinsci.remoting.engine.JnlpProtocol3.disabled=true"
fi
# If both required options are defined, do not pass the parameters
OPT_JENKINS_SECRET=""
if [ -n "$JENKINS_SECRET" ]; then
if [[ "$@" != *"${JENKINS_SECRET}"* ]]; then
OPT_JENKINS_SECRET="${JENKINS_SECRET}"
else
echo "Warning: SECRET is defined twice in command-line arguments and the environment variable"
fi
fi
OPT_JENKINS_AGENT_NAME=""
if [ -n "$JENKINS_AGENT_NAME" ]; then
if [[ "$@" != *"${JENKINS_AGENT_NAME}"* ]]; then
OPT_JENKINS_AGENT_NAME="${JENKINS_AGENT_NAME}"
else
echo "Warning: AGENT_NAME is defined twice in command-line arguments and the environment variable"
fi
fi
curl --silent https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash
#TODO: Handle the case when the command-line and Environment variable contain different values.
#It is fine it blows up for now since it should lead to an error anyway.
exec java $JAVA_OPTS $JNLP_PROTOCOL_OPTS -cp /usr/share/jenkins/slave.jar hudson.remoting.jnlp.Main -headless $TUNNEL $URL $OPT_JENKINS_SECRET $OPT_JENKINS_AGENT_NAME "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment