Let's create bosh release used in BOSH Tutorial!
- BOSH CLI v2.0.36+ is required.
bosh init-release --dir=simple-server-boshrelease --git
cd simple-server-boshrelease
bosh generate-package ruby
curl -L -O -J https://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.4.tar.gz
curl -L -O -J https://rubygems.org/downloads/bundler-1.6.3.gem
bosh add-blob ruby-2.1.4.tar.gz ruby/ruby-2.1.4.tar.gz
bosh add-blob bundler-1.6.3.gem ruby/bundler-1.6.3.gem
rm -f ruby-2.1.4.tar.gz
rm -f bundler-1.6.3.gem
cat <<"EOF" > packages/ruby/spec
---
name: ruby
dependencies: []
files:
- ruby/ruby-2.1.4.tar.gz
- ruby/bundler-1.6.3.gem
EOF
cat <<"EOF" > packages/ruby/packaging
set -e
tar xzf ruby/ruby-*.tar.gz
(
set -e
cd ruby-2.1.4
LDFLAGS="-Wl,-rpath -Wl,${BOSH_INSTALL_TARGET}" CFLAGS='-fPIC' ./configure --prefix=${BOSH_INSTALL_TARGET} --disable-install-doc --with-opt-dir=${BOSH_INSTALL_TARGET} --without-gmp
make
make install
)
${BOSH_INSTALL_TARGET}/bin/gem install ruby/bundler-1.6.3.gem --local --no-ri --no-rdoc
EOF
bosh generate-package simple-server
git submodule add https://github.com/making/simple-server.git src/simple-server
cat <<"EOF" > packages/simple-server/spec
---
name: simple-server
dependencies:
- ruby
files:
- simple-server/**/*
EOF
cat <<"EOF" > packages/simple-server/packaging
set -e
cp -r simple-server/* ${BOSH_INSTALL_TARGET}
cd ${BOSH_INSTALL_TARGET}
mkdir -p ${BOSH_INSTALL_TARGET}/gem_home
/var/vcap/packages/ruby/bin/bundle install --local --no-prune --path ${BOSH_INSTALL_TARGET}/gem_home
EOF
bosh generate-job app
cat <<"EOF" > jobs/app/templates/ctl
#!/bin/bash
RUN_DIR=/var/vcap/sys/run/app
LOG_DIR=/var/vcap/sys/log/app
PIDFILE=$RUN_DIR/app.pid
RUNAS=vcap
export PATH=/var/vcap/packages/ruby/bin:$PATH
export BUNDLE_GEMFILE=/var/vcap/packages/simple-server/Gemfile
export GEM_HOME=/var/vcap/packages/simple-server/gem_home/ruby/2.1.0
function pid_exists() {
ps -p $1 &> /dev/null
}
case $1 in
start)
mkdir -p $RUN_DIR $LOG_DIR
chown -R $RUNAS:$RUNAS $RUN_DIR $LOG_DIR
echo $$ > $PIDFILE
exec chpst -u $RUNAS:$RUNAS \
bundle exec ruby /var/vcap/packages/simple-server/app.rb \
-p <%= p("port") %> \
-o 0.0.0.0 \
>>$LOG_DIR/server.stdout.log 2>>$LOG_DIR/server.stderr.log
;;
stop)
PID=$(head -1 $PIDFILE)
if [ ! -z $PID ] && pid_exists $PID; then
kill $PID
fi
while [ -e /proc/$PID ]; do sleep 0.1; done
rm -f $PIDFILE
;;
*)
echo "Usage: ctl {start|stop|console}" ;;
esac
exit 0
EOF
chmod +x jobs/app/templates/ctl
cat <<"EOF" > jobs/app/monit
check process app
with pidfile /var/vcap/sys/run/app/app.pid
start program "/var/vcap/jobs/app/bin/ctl start"
stop program "/var/vcap/jobs/app/bin/ctl stop"
group vcap
EOF
cat <<"EOF" > jobs/app/spec
---
name: app
templates:
ctl: bin/ctl
packages:
- simple-server
- ruby
properties:
port:
description: "Port on which server is listening"
default: 8080
EOF
bosh generate-job router
cat <<"EOF" > jobs/router/templates/ctl
#!/bin/bash
RUN_DIR=/var/vcap/sys/run/router
LOG_DIR=/var/vcap/sys/log/router
PIDFILE=$RUN_DIR/router.pid
RUNAS=vcap
export PATH=/var/vcap/packages/ruby/bin:$PATH
export BUNDLE_GEMFILE=/var/vcap/packages/simple-server/Gemfile
export GEM_HOME=/var/vcap/packages/simple-server/gem_home/ruby/2.1.0
function pid_exists() {
ps -p $1 &> /dev/null
}
case $1 in
start)
mkdir -p $RUN_DIR $LOG_DIR
chown -R $RUNAS:$RUNAS $RUN_DIR $LOG_DIR
echo $$ > $PIDFILE
export CONFIG_FILE=/var/vcap/jobs/router/config/config.json
exec chpst -u $RUNAS:$RUNAS \
bundle exec ruby /var/vcap/packages/simple-server/router.rb \
-p <%= p("port") %> \
-o 0.0.0.0 \
>>$LOG_DIR/server.stdout.log 2>>$LOG_DIR/server.stderr.log
;;
stop)
PID=$(head -1 $PIDFILE)
if [ ! -z $PID ] && pid_exists $PID; then
kill $PID
fi
while [ -e /proc/$PID ]; do sleep 0.1; done
rm -f $PIDFILE
;;
*)
echo "Usage: ctl {start|stop|console}" ;;
esac
exit 0
EOF
chmod +x jobs/router/templates/ctl
cat <<"EOF" > jobs/router/templates/config.json.erb
{
"servers": <%= p("servers") %>
}
EOF
cat <<"EOF" > jobs/router/monit
check process router
with pidfile /var/vcap/sys/run/router/router.pid
start program "/var/vcap/jobs/router/bin/ctl start"
stop program "/var/vcap/jobs/router/bin/ctl stop"
group vcap
EOF
cat <<"EOF" > jobs/router/spec
---
name: router
templates:
ctl: bin/ctl
config.json.erb: config/config.json
packages:
- simple-server
- ruby
properties:
port:
description: "Port on which server is listening"
default: 8080
servers:
description: "List of servers to redirect requests"
default: []
EOF
cat <<"EOF" > config/final.yml
---
blobstore:
provider: local
options:
blobstore_path: /tmp/simple-server
final_name: simple-server
EOF
bosh create-release --name=simple-server --force --timestamp-version --tarball=/tmp/simple-server-boshrelease.tgz
bosh upload-release /tmp/simple-server-boshrelease.tgz
cat <<"EOF" > manifest.yml
---
name: simple-server
releases:
- name: simple-server
version: latest
stemcells:
- os: ubuntu-trusty
alias: trusty
version: latest
instance_groups:
- name: app
jobs:
- name: app
release: simple-server
properties:
port: 8080
instances: 2
stemcell: trusty
azs: [z1]
vm_type: default
networks:
- name: default
static_ips: ((app-ips))
- name: router
jobs:
- name: router
release: simple-server
properties:
port: 8080
servers: ((servers))
instances: 1
stemcell: trusty
azs: [z1]
vm_type: default
networks:
- name: default
static_ips: ((router-ip))
update:
canaries: 1
max_in_flight: 3
canary_watch_time: 30000-600000
update_watch_time: 5000-600000
EOF
bosh deploy -d simple-server manifest.yml -v app-ips="[10.0.16.30,10.0.16.31]" -v servers="['http://10.0.16.30:8080', 'http://10.0.16.31:8080']" -v router-ip=10.0.16.40
cat <<"EOF" > jobs/app/spec
---
name: app
templates:
ctl: bin/ctl
provides:
- name: app
type: conn
properties:
- port
packages:
- simple-server
- ruby
properties:
port:
description: "Port on which server is listening"
default: 8080
EOF
cat <<"EOF" > jobs/router/spec
---
name: router
templates:
ctl: bin/ctl
config.json.erb: config/config.json
consumes:
- name: app
type: conn
packages:
- simple-server
- ruby
properties:
port:
description: "Port on which server is listening"
default: 8080
EOF
cat <<"EOF" > jobs/router/templates/config.json.erb
{
"servers": <%= JSON.dump(link('app').instances.map { |x| 'http://' + x.address + ':' + link('app').p('port').to_s }) %>
}
EOF
cat <<"EOF" > manifest.yml
---
name: simple-server
releases:
- name: simple-server
version: latest
stemcells:
- os: ubuntu-trusty
alias: trusty
version: latest
instance_groups:
- name: app
jobs:
- name: app
release: simple-server
properties:
port: 8080
instances: 2
stemcell: trusty
azs: [z1]
vm_type: default
networks:
- name: default
- name: router
jobs:
- name: router
release: simple-server
properties:
port: 8080
instances: 1
stemcell: trusty
azs: [z1]
vm_type: default
networks:
- name: default
static_ips: ((router-ip))
update:
canaries: 1
max_in_flight: 3
canary_watch_time: 30000-600000
update_watch_time: 5000-600000
EOF
bosh create-release --name=simple-server --force --timestamp-version --tarball=/tmp/simple-server-boshrelease.tgz
bosh upload-release /tmp/simple-server-boshrelease.tgz
bosh deploy -d simple-server manifest.yml -v router-ip=10.0.16.40
rm -rf packages/ruby
cd ..
git clone git@github.com:bosh-packages/ruby-release.git
cd simple-server-boshrelease
bosh vendor-package ruby-2.4 ../ruby-release
cat <<"EOF" > packages/simple-server/spec
---
name: simple-server
dependencies:
- ruby-2.4
files:
- simple-server/**/*
EOF
cat <<"EOF" > packages/simple-server/packaging
set -e
source /var/vcap/packages/ruby-2.4/bosh/compile.env
cp -r simple-server/* ${BOSH_INSTALL_TARGET}
cp -r simple-server/* ./
bosh_bundle_local
bosh_generate_runtime_env
EOF
cat <<"EOF" > jobs/app/spec
---
name: app
templates:
ctl: bin/ctl
provides:
- name: app
type: conn
properties:
- port
packages:
- simple-server
- ruby-2.4
properties:
port:
description: "Port on which server is listening"
default: 8080
EOF
cat <<"EOF" > jobs/router/spec
---
name: router
templates:
ctl: bin/ctl
config.json.erb: config/config.json
consumes:
- name: app
type: conn
packages:
- simple-server
- ruby-2.4
properties:
port:
description: "Port on which server is listening"
default: 8080
EOF
cat <<"EOF" > jobs/app/templates/ctl
#!/bin/bash
RUN_DIR=/var/vcap/sys/run/app
LOG_DIR=/var/vcap/sys/log/app
PIDFILE=$RUN_DIR/app.pid
RUNAS=vcap
source /var/vcap/packages/ruby-2.4/bosh/runtime.env
source /var/vcap/packages/simple-server/bosh/runtime.env
function pid_exists() {
ps -p $1 &> /dev/null
}
case $1 in
start)
mkdir -p $RUN_DIR $LOG_DIR
chown -R $RUNAS:$RUNAS $RUN_DIR $LOG_DIR
echo $$ > $PIDFILE
exec chpst -u $RUNAS:$RUNAS \
bundle exec ruby /var/vcap/packages/simple-server/app.rb \
-p <%= p("port") %> \
-o 0.0.0.0 \
>>$LOG_DIR/server.stdout.log 2>>$LOG_DIR/server.stderr.log
;;
stop)
PID=$(head -1 $PIDFILE)
if [ ! -z $PID ] && pid_exists $PID; then
kill $PID
fi
while [ -e /proc/$PID ]; do sleep 0.1; done
rm -f $PIDFILE
;;
*)
echo "Usage: ctl {start|stop|console}" ;;
esac
exit 0
EOF
cat <<"EOF" > jobs/router/templates/ctl
#!/bin/bash
RUN_DIR=/var/vcap/sys/run/router
LOG_DIR=/var/vcap/sys/log/router
PIDFILE=$RUN_DIR/router.pid
RUNAS=vcap
source /var/vcap/packages/ruby-2.4/bosh/runtime.env
source /var/vcap/packages/simple-server/bosh/runtime.env
function pid_exists() {
ps -p $1 &> /dev/null
}
case $1 in
start)
mkdir -p $RUN_DIR $LOG_DIR
chown -R $RUNAS:$RUNAS $RUN_DIR $LOG_DIR
echo $$ > $PIDFILE
export CONFIG_FILE=/var/vcap/jobs/router/config/config.json
exec chpst -u $RUNAS:$RUNAS \
bundle exec ruby /var/vcap/packages/simple-server/router.rb \
-p <%= p("port") %> \
-o 0.0.0.0 \
>>$LOG_DIR/server.stdout.log 2>>$LOG_DIR/server.stderr.log
;;
stop)
PID=$(head -1 $PIDFILE)
if [ ! -z $PID ] && pid_exists $PID; then
kill $PID
fi
while [ -e /proc/$PID ]; do sleep 0.1; done
rm -f $PIDFILE
;;
*)
echo "Usage: ctl {start|stop|console}" ;;
esac
exit 0
EOF
bosh create-release --name=simple-server --force --timestamp-version --tarball=/tmp/simple-server-boshrelease.tgz
bosh upload-release /tmp/simple-server-boshrelease.tgz
bosh deploy -d simple-server manifest.yml -v router-ip=10.0.16.40