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

Default workers inside docker image #1

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
29 changes: 29 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.gitignore
Dockerfile
.eunit
deps
*.o
*.beam
*.plt
erl_crash.dump
ebin
node/rel/mzbench
server/rel/mzbench_api
server/priv/http_root/js/bundle.js
server/dashboard/test/es5Checker.js
.make
.rebar
log
*.rpm
*.tgz
pkgroot
dialyzer.log
*.pyc
.DS_Store
server/data
server/plugins
acceptance_tests/test_server.config
_build
rebar.lock
site
priv/http_root/index.html
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
14 Sep 2018 Version 0.5.6
* Updated Docker buildings
* Fix k8s plugin worker installation

22 May 2018 Version 0.5.5
* Support for custom images with workers

Expand Down
114 changes: 68 additions & 46 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,54 +1,76 @@
FROM erlang:20.3.2-alpine

# install packages
RUN apk update && apk add --no-cache \
bash \
bc \
g++ \
git \
make \
musl-dev \
net-tools \
openssh openssh-server \
openssl \
py2-pip \
rsync \
wget \
zlib-dev \
;

# Download kubectl
ARG KUBECTL_VERSION=1.9.6
ARG KUBECTL_CHECKSUM=e6aa618d682d0bcc90602cbf2e22a134d36af7199d7081015042eca02ba36368
RUN wget -O /usr/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl && \
echo "${KUBECTL_CHECKSUM} /usr/bin/kubectl" | sha256sum -c - && \
chmod +x /usr/bin/kubectl

WORKDIR /opt/mzbench
### --- Build mzbench artifacts --- ###
FROM erlang:20.3.8-alpine as build

ENV ORIG_PATH=$PATH
ENV CODE_LOADING_MODE=interactive

ENV MZBENCH_SRC_DIR /opt/mzbench_src
ENV MZBENCH_API_DIR /opt/mzbench_api
ENV HOME_DIR /root

WORKDIR $MZBENCH_SRC_DIR

# Install packages
RUN apk add --no-cache g++ make musl-dev zlib-dev py2-pip openssl git rsync

COPY . .
# Clean sources just in case you build smth in the same folder
RUN make -C /opt/mzbench/server clean \
&& make -C /opt/mzbench/node clean \
&& find . -name "*.so" -or -name "*.o" | xargs -I{} rm {}

# Compile and configure server
RUN pip install -r requirements.txt \
&& make -C /opt/mzbench/server generate \
&& mkdir -p /etc/mzbench /root/.ssh \
&& echo "[{mzbench_api, [{network_interface, \"0.0.0.0\"},{listen_port, 80}]}]." > /etc/mzbench/server.config \
&& ssh-keygen -A \
&& cp /etc/ssh/ssh_host_rsa_key /root/.ssh/id_rsa \
&& cat /etc/ssh/ssh_host_rsa_key.pub >> /root/.ssh/authorized_keys \
&& chmod 0600 /root/.ssh/authorized_keys
# Install Mzbench_api server, Node, Workers through default path
# - Mzbench_api application would be installed to ${MZBENCH_API_DIR}
# - Node application would be installed to ${HOME_DIR}/.local/share
RUN mkdir -p ${HOME_DIR}/.local/share/mzbench_workers \
&& pip install -r requirements.txt \
&& make -C ./server generate \
&& cp -R ./server/_build/default/rel/mzbench_api ${MZBENCH_API_DIR}/ \
&& make -C ./node install \
&& make -C ./node local_tgz \
&& ln -s ${HOME_DIR}/.local/cache/mzbench_api/packages/node-*_erts*.tgz ${HOME_DIR}/.local/cache/mzbench_api/packages/node-someversion-someos.tgz \
&& ln -s ${HOME_DIR}/.local/cache/mzbench_api/packages/node-*_erts*.tgz ${HOME_DIR}/.local/cache/mzbench_api/packages/node-$(git rev-parse HEAD)-someos.tgz

# Install Workers through default path
# - Workers packages would be stored at ${HOME_DIR}/.local/share/mzbench_workers
RUN make -C ./server extract-workers

# Compile and install worker into the /root/.local/share
RUN make -C /opt/mzbench/node install

### --- Final small image --- ###
FROM erlang:20.3.8-alpine

# Config file can be added via runtime env MZBENCH_CONFIG_FILE:
# docker run --env MZBENCH_CONFIG_FILE=<path>

# env variables can be changed at runtime using `docker run --env ...`
ENV ORIG_PATH=$PATH
ENV CODE_LOADING_MODE=interactive
# config can be added via runtime env
# docker run --env MZBENCH_CONFIG_FILE=<path>
CMD /opt/mzbench/server/_build/default/rel/mzbench_api/bin/mzbench_api foreground

# Refer https://kubernetes.io/docs/setup/release/notes/
ARG KUBECTL_VERSION=1.10.7
ARG KUBECTL_CHECKSUM=169b57c6707ed8d8be9643b0088631e5c0c6a37a5e99205f03c1199cd32bc61e

ENV MZBENCH_API_DIR /opt/mzbench_api
ENV HOME_DIR /root

COPY requirements.txt /tmp

# Install packages, install kubectl (refer https://kubernetes.io/docs/setup/release/notes/),
# create ssh keys, make server.config
RUN apk add --no-cache libstdc++ git curl openssh openssh-server bash rsync net-tools py2-pip \
&& curl -O -L https://dl.k8s.io/v${KUBECTL_VERSION}/kubernetes-client-linux-amd64.tar.gz \
&& echo "${KUBECTL_CHECKSUM} kubernetes-client-linux-amd64.tar.gz" | sha256sum -c - \
&& tar -xf kubernetes-client-linux-amd64.tar.gz \
&& mv kubernetes/client/bin/kubectl /usr/bin/kubectl \
&& rm -rf kubernete* \
&& chmod +x /usr/bin/kubectl \
&& mkdir -p /etc/mzbench ${HOME_DIR}/.local/share/mzbench_workers ${HOME_DIR}/.ssh \
&& ssh-keygen -A \
&& cp /etc/ssh/ssh_host_rsa_key ${HOME_DIR}/.ssh/id_rsa \
&& cat /etc/ssh/ssh_host_rsa_key.pub >> ${HOME_DIR}/.ssh/authorized_keys \
&& chmod 0600 ${HOME_DIR}/.ssh/authorized_keys \
&& pip install -r /tmp/requirements.txt \
&& echo "[{mzbench_api, [ {auto_update_deployed_code, disable}, {custom_os_code_builds, disable}, {network_interface, \"0.0.0.0\"},{listen_port, 80}]}]." > /etc/mzbench/server.config

COPY --from=build $MZBENCH_API_DIR $MZBENCH_API_DIR
COPY --from=build ${HOME_DIR}/.local ${HOME_DIR}/.local

EXPOSE 80
WORKDIR $MZBENCH_API_DIR

CMD $MZBENCH_API_DIR/bin/mzbench_api foreground
18 changes: 15 additions & 3 deletions bin/mzbench
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Usage:
[--node_commit=<commit>]
[--deallocate_after_bench=<deallocate_after_bench>]
[--provision_nodes=<provision_nodes>]
[--provision_workers=<provision_workers>]
[--name=<benchmark_name>]
[--cloud=<cloud_provider_name>]
[--tags=<tags>]
Expand Down Expand Up @@ -109,6 +110,11 @@ Options:
to "true" indicates to perform nodes provision. Disabling
it is useful when reusing already preallocated and
provisioned nodes.
--provision_workers <provision_workers>
Either "true" or "false". Default is "true". Setting this
to "true" indicates to perform workers provision. Disabling
it is useful when reusing already preallocated and
provisioned workers.
--name <benchmark_name>
Set benchmark name.
--cloud <cloud_provider_name>
Expand Down Expand Up @@ -317,18 +323,18 @@ def pretty_print(data):
print()

def run(host, script_file, script_content, email, nodes, workers_per_node,
node_commit, deallocate_after_bench, provision_nodes,
node_commit, deallocate_after_bench, provision_nodes, provision_workers,
name, cloud, tags, env, no_cert_check = False, exclusive = None):
bench_id = start(host, script_file, script_content, email, node_commit,
nodes, workers_per_node, deallocate_after_bench, provision_nodes,
name, cloud, tags, env, no_cert_check, exclusive)
provision_workers, name, cloud, tags, env, no_cert_check, exclusive)
response = status(host, bench_id, wait=True, no_cert_check = no_cert_check)
if response[u'status'] == u'failed':
print('Bench failed')
sys.exit(3)

def start(host, script_file, script_content, email, node_commit, nodes,
workers_per_node, deallocate_after_bench, provision_nodes,
workers_per_node, deallocate_after_bench, provision_nodes, provision_workers,
name, cloud, tags, env, no_cert_check = False, exclusive = None):
try:
response = api.start(host,
Expand All @@ -338,6 +344,7 @@ def start(host, script_file, script_content, email, node_commit, nodes,
node_commit=node_commit,
deallocate_after_bench=deallocate_after_bench,
provision_nodes=provision_nodes,
provision_workers=provision_workers,
benchmark_name=name,
cloud=cloud,
tags=tags,
Expand Down Expand Up @@ -684,6 +691,11 @@ def augment_args(args):
args['--provision_nodes']))
sys.exit(4)

if args['--provision_workers'] not in [None, 'true', 'false']:
print("invalid value for --provision_workers: {0}".format(
args['--provision_workers']))
sys.exit(4)

script_file = args['<script_file>']
if script_file:
if not os.path.exists(script_file):
Expand Down
3 changes: 3 additions & 0 deletions doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ deallocate_after_bench=false
provision_nodes=false
: Pass to skip MZBench installation on the nodes.

provision_workers=false
: Pass to skip Workers installation on the nodes.

node_commit
: Commit hash or branch name in the [MZBench repository](https://github.com/satori-com/mzbench/) that should be installed on the nodes.

Expand Down
3 changes: 3 additions & 0 deletions doc/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ Optional params:
`--provision_nodes false`
: Skip MZBench installation on the nodes.

`--provision_workers false`
: Skip Workers installation on the nodes.

`--node_commit=<commit>`
: Commit hash or branch name in the MZBench repository pointing to the MZBench version to install on the nodes.

Expand Down
3 changes: 3 additions & 0 deletions doc_old/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ deallocate_after_bench=false
provision_nodes=false
: Pass to skip MZBench installation on the nodes.

provision_workers=false
: Pass to skip installation Workers on the nodes.

node_commit
: Commit hash or branch name in the [MZBench repository](https://github.com/satori-com/mzbench/) that should be installed on the nodes.

Expand Down
3 changes: 3 additions & 0 deletions doc_old/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ Optional params:
`--provision_nodes false`
: Skip MZBench installation on the nodes.

`--provision_workers false`
: Skip Workers installation on the nodes.

`--node_commit=<commit>`
: Commit hash or branch name in the MZBench repository pointing to the MZBench version to install on the nodes.

Expand Down
6 changes: 5 additions & 1 deletion lib/mzbench_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class MZBenchAPIException(Exception):

def start(host, script_file, script_content,
node_commit = None, nodes = None, workers_per_node = None, deallocate_after_bench = None,
provision_nodes = None, benchmark_name = None,
provision_nodes = None, provision_workers = None, benchmark_name = None,
cloud = None, tags = None, emails=[], includes=[], env={}, no_cert_check = False,
exclusive = None
):
Expand All @@ -41,6 +41,8 @@ def start(host, script_file, script_content,
:type deallocate_after_bench: "true" or "false"
:param provision_nodes: Install required software
:type provision_nodes: "true" or "false"
:param provision_workers: Install workers
:type provision_workers: "true" or "false"
:param benchmark_name: Set benchmark name
:type benchmark_name: str or unicode
:param cloud: Specify cloud provider to use
Expand Down Expand Up @@ -84,6 +86,8 @@ def start(host, script_file, script_content,
params += [('deallocate_after_bench', deallocate_after_bench)]
if provision_nodes is not None:
params += [('provision_nodes', provision_nodes)]
if provision_workers is not None:
params += [('provision_workers', provision_workers)]
if benchmark_name is not None:
params += [('benchmark_name', benchmark_name)]
if cloud is not None:
Expand Down
50 changes: 28 additions & 22 deletions server/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,7 @@ SOURCES := $(shell find src dashboard test -name .eunit -prune -o -name node_mod
MZBENCH_COMMON_SOURCES := $(wildcard ../common_apps/*/include/*) $(wildcard ../common_apps/*/src/*) $(wildcard ../common_apps/*/rebar.config)
RELEASE_BINARY := _build/default/rel/$(SERVICE_NAME)/bin/$(SERVICE_NAME)

define RPM_HELPER
import glob
import shutil
import subprocess
import os.path
for file in glob.glob('../workers/*'):
subprocess.check_call(["make", "-C", file, "generate_tgz"])
worker_name = os.path.basename(file)
shutil.copyfile(file + "/" + worker_name + "_worker.tgz", "tmproot/opt/mzbench_api/cache/" + worker_name + "-someversion-someos.tgz")
endef
export RPM_HELPER
TMP_ROOT:= $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))/tmproot

.PHONY: compile
compile: .make/compilation-up-to-date
Expand All @@ -26,23 +16,39 @@ compile: .make/compilation-up-to-date
console: $(RELEASE_BINARY)
$(RELEASE_BINARY) console

.PHONY: tmp-dir
tmp-dir:
-rm -rf $(TMP_ROOT)
mkdir -p $(TMP_ROOT)/opt/mzbench_api/cache

.PHONY: build-workers
build-workers:
cd ../workers/ && \
for WORKER in * ; do \
make -C $${WORKER}/ generate_tgz && \
cp $${WORKER}/$${WORKER}_worker.tgz $(TMP_ROOT)/opt/mzbench_api/cache/$${WORKER}-someversion-someos.tgz ; \
done

.PHONY: extract-workers
extract-workers: tmp-dir build-workers
cd $(TMP_ROOT)/opt/mzbench_api/cache/ && \
for WORKER_TGZ in * ; do \
tar xzf $${WORKER_TGZ} -C ~/.local/share/mzbench_workers ; \
done

.PHONY: rpm
rpm: generate
rpm: generate tmp-dir build-workers
echo "You need to disable custom_os_code_builds and auto_update_deployed_code to make your RPM work"
-rm -rf tmproot
mkdir -p tmproot/opt/
cp -R _build/default/rel/mzbench_api tmproot/opt
mkdir -p tmproot/opt/mzbench_api/cache
cp -R _build/default/rel/mzbench_api $(TMP_ROOT)/opt
make -C ../node generate_tgz
cp ../node/node.tgz tmproot/opt/mzbench_api/cache/node-someversion-someos.tgz
python -c "$$RPM_HELPER"
cp ../node/node.tgz $(TMP_ROOT)/opt/mzbench_api/cache/node-someversion-someos.tgz
-git clone https://github.com/flussonic/epm _build/epm
EPM="-s dir --url http://github.com/machinezone/mzbench --description 'Benchmark server' \
-m 'Info <[email protected]>' --vendor 'MZ' --license BSD"
cd tmproot && ../_build/epm/epm.erl -f -t deb -n mzbench -v 0.5.5 $(EPM) -a amd64 \
--category net opt
cd tmproot && ../_build/epm/epm.erl -f -t rpm -n mzbench -v 0.5.5 $(EPM) -a amd64 \
--category Server/Benchmark opt
cd $(TMP_ROOT) && ../_build/epm/epm.erl -f -t deb -n mzbench -v 0.5.6 $(EPM) -a amd64 \
--category net opt
cd $(TMP_ROOT) && ../_build/epm/epm.erl -f -t rpm -n mzbench -v 0.5.6 $(EPM) -a amd64 \
--category Server/Benchmark opt

.PHONY: js-dev
js-dev: compile
Expand Down
2 changes: 1 addition & 1 deletion server/rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
]}.

{relx, [
{release, {mzbench_api, "0.5.5"},
{release, {mzbench_api, "0.5.6"},
[mzbench_api]},
{vm_args, "rel/files/vm.args"},
{sys_config, "rel/files/sys.config"},
Expand Down
1 change: 1 addition & 0 deletions server/src/mzb_api_bench.erl
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ init([Id, Params]) ->
env => mzbl_script:normalize_env(generate_bench_env(Id, Params)),
deallocate_after_bench => maps:get(deallocate_after_bench, Params),
provision_nodes => ProvisionNodes,
provision_workers => maps:get(provision_workers, Params),
req_host => maps:get(req_host, Params),
initial_user => maps:get(user, Params),
director_host => undefined,
Expand Down
1 change: 1 addition & 0 deletions server/src/mzb_api_endpoints.erl
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ parse_start_params(Req) ->
{emulate_bench_crash, single_value, fun binary_to_bool/1, false},
{deallocate_after_bench, single_value, fun binary_to_bool/1, true},
{provision_nodes, single_value, fun binary_to_bool/1, true},
{provision_workers, single_value, fun binary_to_bool/1, true},
{benchmark_name, single_value, fun erlang:binary_to_list/1, undefined},
{cloud, single_value, fun (N) -> erlang:binary_to_atom(N, latin1) end, undefined},
{exclusive, single_value, fun erlang:binary_to_list/1, []},
Expand Down
Loading