bosh-gen 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/ChangeLog.md +13 -0
  2. data/lib/bosh/gen/cli.rb +45 -29
  3. data/lib/bosh/gen/generators/deployment_manifest_generator.rb +7 -3
  4. data/lib/bosh/gen/generators/extract_job_generator.rb +37 -6
  5. data/lib/bosh/gen/generators/extract_package_generator.rb +23 -5
  6. data/lib/bosh/gen/generators/job_generator.rb +34 -16
  7. data/lib/bosh/gen/generators/job_generator/templates/examples/%job_name%_nginx_rack/nginx_puma_migrate.yml +14 -0
  8. data/lib/bosh/gen/generators/job_generator/templates/examples/%job_name%_nginx_rack/nginx_rackup.yml.tt +8 -0
  9. data/lib/bosh/gen/generators/job_generator/templates/examples/%job_name%_simple/default.yml +2 -0
  10. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/monit.tt +13 -0
  11. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/%job_name%_rack_ctl.tt +59 -0
  12. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/ctl_db_utils.sh.erb +54 -0
  13. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/ctl_nginx.sh.erb +17 -0
  14. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/ctl_redis_utils.sh.erb +18 -0
  15. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/ctl_setup.sh.erb +48 -0
  16. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/ctl_start.sh.erb +59 -0
  17. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/ctl_utils.sh +148 -0
  18. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/monit_debugger +13 -0
  19. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/nginx_ctl.tt +41 -0
  20. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/bin/rails_ctl_setup.sh.erb +40 -0
  21. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/config/database.yml.erb +17 -0
  22. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/config/mime.types +73 -0
  23. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/config/nginx.conf.erb +150 -0
  24. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/config/nginx_proxy.conf +11 -0
  25. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_nginx_rack/templates/config/redis.yml.erb +6 -0
  26. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/monit.tt +5 -0
  27. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/templates/bin/%job_name%_ctl.tt +36 -0
  28. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/templates/bin/monit_debugger +13 -0
  29. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/templates/data/properties.sh.erb +10 -0
  30. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/templates/helpers/ctl_setup.sh +81 -0
  31. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/templates/helpers/ctl_utils.sh +156 -0
  32. data/lib/bosh/gen/generators/package_generator.rb +56 -10
  33. data/lib/bosh/gen/models.rb +1 -0
  34. data/lib/bosh/gen/models/bosh_config.rb +15 -0
  35. data/lib/bosh/gen/models/deployment_manifest.rb +5 -0
  36. data/lib/bosh/gen/version.rb +1 -1
  37. data/spec/fixtures/bosh_config/multiple_boshes.yml +34 -0
  38. data/spec/fixtures/deployment_manifests/2_jobs_1_ip_8196_disk.yml +2 -2
  39. data/spec/fixtures/deployment_manifests/2_jobs_2_ips_no_disk.yml +2 -2
  40. data/spec/generators/generator_spec_helper.rb +102 -0
  41. data/spec/generators/jobs/webapp_job_generator_spec.rb +68 -0
  42. data/spec/models/bosh_config_spec.rb +11 -0
  43. metadata +38 -8
  44. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%/monit.tt +0 -5
  45. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%/templates/%job_name%_ctl.tt +0 -62
  46. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_rubyrack/monit.tt +0 -5
  47. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_rubyrack/templates/%job_name%_ctl.tt +0 -64
@@ -0,0 +1,54 @@
1
+ <% if properties.postgres %>
2
+ PG_PACKAGE_DIR=/var/vcap/package/postgres
3
+ function database_ready() {
4
+ DB_HOST='<%= properties.postgres.host %>'
5
+ DB_PORT='<%= properties.postgres.port || 5432 %>'
6
+ DB_USER='<%= properties.postgres.user %>'
7
+ DB_PASSWORD='<%= properties.postgres.password %>'
8
+ DB_NAME='<%= properties.postgres.database %>'
9
+ echo Testing postgresl: psql -d $DB_NAME -p $DB_PORT -U vcap -c "select 1;"
10
+ LD_LIBRARY_PATH=$PG_PACKAGE_DIR/lib $PG_PACKAGE_DIR/bin/psql -d $DB_NAME -p $DB_PORT -U $DB_USER -c "select 1;"
11
+ }
12
+ <% else %>
13
+ # No database or SQLite database
14
+ function database_ready() {
15
+ true
16
+ }
17
+ <% end %>
18
+
19
+ function wait_for_database() {
20
+ while [[ ! database_ready ]]
21
+ do
22
+ echo "Waiting for database availability"
23
+ sleep 1;
24
+ done
25
+ }
26
+
27
+ # Look for known types of config files
28
+ # and if found, symlink into target location
29
+ # in application
30
+ #
31
+ # config/wp-config.php -> wp-config.php
32
+ # config/database.yml -> config/database.yml
33
+ function link_sql_db_config() {
34
+ possible_job_config=(config/database.yml config/wp-config.php)
35
+ target_app_config=(config/database.yml wp-config.php)
36
+ list_size=${#possible_job_config[@]}
37
+ found_config='none'
38
+ for (( i = 0; i < $list_size; i++ )); do
39
+ job_config=${possible_job_config[i]}
40
+ app_config=${target_app_config[i]}
41
+ if [[ -f $JOB_DIR/${job_config} ]]
42
+ then
43
+ link_job_file_to_package ${job_config} ${app_config}
44
+ found_config=${app_config}
45
+ fi
46
+ done
47
+
48
+ if [[ "${found_config}" = "none" ]]
49
+ then
50
+ echo "ERROR: link_sql_db_config - job does not contain a supported db config file"
51
+ echo "Please add to job $JOB_NAME a template from: ${possible_job_config[@]}"
52
+ exit 1
53
+ fi
54
+ }
@@ -0,0 +1,17 @@
1
+ # Setup HTTP_PROXY, HTTPS_PROXY, NO_PROXY as necessary
2
+
3
+ # https://github.com/pmirshad/cgit-on-nginx/wiki/Installing-cgit-with-nginx-on-Ubuntu-11.10
4
+ <% if properties.env %>
5
+ <% if properties.env.http_proxy %>
6
+ export HTTP_PROXY='<%= properties.env.http_proxy %>'
7
+ export http_proxy='<%= properties.env.http_proxy %>'
8
+ <% end %>
9
+ <% if properties.env.https_proxy %>
10
+ export HTTPS_PROXY='<%= properties.env.https_proxy %>'
11
+ export https_proxy='<%= properties.env.https_proxy %>'
12
+ <% end %>
13
+ <% if properties.env.no_proxy %>
14
+ export NO_PROXY='<%= properties.env.no_proxy %>'
15
+ export no_proxy='<%= properties.env.no_proxy %>'
16
+ <% end %>
17
+ <% end %>
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+
3
+ REDIS='<%= properties.redis ? 1 : 0 %>'
4
+
5
+ # Usage: link_redis_config yaml config/redis.yml
6
+ function link_redis_config() {
7
+ format=$1 # e.g. yaml
8
+ target_file=${2:-config/redis.yml} # e.g. config/redis.yml
9
+ if [[ "${format}" != "yaml" ]]
10
+ then
11
+ echo "ERROR: 'link_redis_config ${format}' is not supported. Only supported format: yaml"
12
+ exit 1
13
+ fi
14
+ if [[ "$REDIS" = '1' ]]
15
+ then
16
+ link_job_file_to_package ${app_config}
17
+ fi
18
+ }
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Setup env vars and folders for the ctl script
4
+ # This helps keep the ctl script as readable
5
+ # as possible
6
+
7
+ set -e # exit immediately if a simple command exits with a non-zero status
8
+ set -u # report the usage of uninitialized variables
9
+
10
+ export JOB_NAME='<%= name %>'
11
+ export JOB_DIR=/var/vcap/jobs/$JOB_NAME
12
+ chmod 755 $JOB_DIR # to access file via symlink
13
+
14
+ # the package that contains the application code
15
+ WEBAPP_PACKAGE='<%= properties.webapp && properties.webapp.package %>'
16
+ WEBAPP_DIR=/var/vcap/packages/$WEBAPP_PACKAGE
17
+ if [[ "$WEBAPP_PACKAGE" = '' ]]
18
+ then
19
+ echo 'ERROR: $WEBAPP_PACKAGE not set before bin/ctl_setup.sh'
20
+ exit 1
21
+ fi
22
+
23
+ source $JOB_DIR/bin/ctl_utils.sh
24
+ redirect_output $JOB_NAME
25
+
26
+ export HOME=${HOME:-/home/vcap}
27
+
28
+ # Add all packages' /bin & /sbin into $PATH
29
+ for package_bin_dir in $(ls -d /var/vcap/packages/*/{,s}bin)
30
+ do
31
+ export PATH=${package_bin_dir}:$PATH
32
+ done
33
+
34
+ # Setup log, run and tmp folders
35
+
36
+ RUN_DIR=/var/vcap/sys/run/$JOB_NAME
37
+ LOG_DIR=/var/vcap/sys/log/$JOB_NAME
38
+ TMPDIR=/var/vcap/sys/tmp/$JOB_NAME
39
+ for dir in $RUN_DIR $LOG_DIR $TMPDIR
40
+ do
41
+ mkdir -p ${dir}
42
+ chown vcap:vcap ${dir}
43
+ done
44
+
45
+ export C_INCLUDE_PATH=/var/vcap/packages/mysqlclient/include/mysql:/var/vcap/packages/sqlite/include:/var/vcap/packages/libpq/include
46
+ export LIBRARY_PATH=/var/vcap/packages/mysqlclient/lib/mysql:/var/vcap/packages/sqlite/lib:/var/vcap/packages/libpq/lib
47
+
48
+ PIDFILE=$RUN_DIR/$JOB_NAME.pid
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Either:
4
+ # properties:
5
+ # webapp:
6
+ # appstack: puma
7
+ # puma:
8
+ # threads:
9
+ # min: 0
10
+ # max: 16
11
+ #
12
+ # Or PHP-FPM:
13
+ # properties:
14
+ # webapp:
15
+ # appstack: php-fpm
16
+ #
17
+ # Or (default)
18
+ # properties:
19
+ # webapp:
20
+ # appstack: rackup
21
+ #
22
+ # Requires env variables:
23
+ # * $WEBAPP_DIR
24
+ # * $PIDFILE
25
+ # * $PORT
26
+ appstack='<%= properties.webapp && properties.webapp.appstack %>'
27
+
28
+ echo "Launching $JOB_NAME within $WEBAPP_DIR with ${appstack}"
29
+ wait_for_database
30
+
31
+ if [[ "${appstack}" = "puma" ]]
32
+ then
33
+ <% puma_threads = properties.webapp.puma && properties.webapp.puma.threads %>
34
+ MIN_THREADS=<%= (puma_threads && puma_threads.min) || 0 %>
35
+ MAX_THREADS=<%= (puma_threads && puma_threads.max) || 16 %>
36
+ exec bundle exec puma --pidfile $PIDFILE -p $PORT -t $MIN_THREADS:$MAX_THREADS \
37
+ >>$LOG_DIR/webapp.stdout.log \
38
+ 2>>$LOG_DIR/webapp.stderr.log || exit 1
39
+
40
+ elif [[ "${appstack}" = "rackup" ]]
41
+ then
42
+ exec bundle exec rackup -D -P $PIDFILE -p $PORT \
43
+ >>$LOG_DIR/webapp.stdout.log \
44
+ 2>>$LOG_DIR/webapp.stderr.log || exit 1
45
+
46
+ elif [[ "${appstack}" = "phpfpm" || "${appstack}" = "php-fpm" ]]
47
+ then
48
+ /var/vcap/packages/php5/sbin/php-fpm \
49
+ -c $JOB_DIR/etc/php.ini \
50
+ --fpm-config $JOB_DIR/etc/php-fpm.conf \
51
+ --pid $PIDFILE
52
+
53
+ # else invalid appstack requested
54
+ else
55
+ echo "ERROR: properties.webapp.appstack = ${appstack}. Valid values: puma, rackup"
56
+ exit 1
57
+ fi
58
+
59
+ chown vcap:vcap $PIDFILE
@@ -0,0 +1,148 @@
1
+ # Helper functions used by ctl scripts
2
+
3
+ # links a file (probably a config file) into a package
4
+ # Example usage:
5
+ # link_job_file_to_package config/redis.yml [config/redis.yml]
6
+ # link_job_file_to_package config/wp-config.php wp-config.php
7
+ link_job_file_to_package() {
8
+ source_job_file=$1
9
+ target_package_file=${2:-$source_job_file}
10
+
11
+ full_job_file=$JOB_DIR/${source_job_file}
12
+ full_package_file=$WEBAPP_DIR/${target_package_file}
13
+ echo link_job_file_to_package $full_job_file $full_package_file
14
+ if [[ ! -f ${full_job_file} ]]
15
+ then
16
+ echo "File to link ${full_job_file} does not exist"
17
+ else
18
+ # Create/recreate the symlink to current job file
19
+ # If another process is using the file, it won't be
20
+ # deleted, so don't attempt to create the symlink
21
+ echo "Linking ${source_job_file} -> ${full_package_file}"
22
+ mkdir -p $(dirname ${full_package_file})
23
+ ln -nfs ${full_job_file} ${full_package_file}
24
+ fi
25
+ }
26
+
27
+
28
+ # If loaded within monit ctl scripts then pipe output
29
+ # If loaded from 'source ../utils.sh' then normal STDOUT
30
+ redirect_output() {
31
+ SCRIPT=$1
32
+ mkdir -p /var/vcap/sys/log/monit
33
+ exec 1>> /var/vcap/sys/log/monit/$SCRIPT.log
34
+ exec 2>> /var/vcap/sys/log/monit/$SCRIPT.err.log
35
+ }
36
+
37
+ pid_guard() {
38
+ pidfile=$1
39
+ name=$2
40
+
41
+ if [ -f "$pidfile" ]; then
42
+ pid=$(head -1 "$pidfile")
43
+
44
+ if [ -n "$pid" ] && [ -e /proc/$pid ]; then
45
+ echo "$name is already running, please stop it first"
46
+ exit 1
47
+ fi
48
+
49
+ echo "Removing stale pidfile..."
50
+ rm $pidfile
51
+ fi
52
+ }
53
+
54
+ wait_pid() {
55
+ pid=$1
56
+ try_kill=$2
57
+ timeout=${3:-0}
58
+ force=${4:-0}
59
+ countdown=$(( $timeout * 10 ))
60
+
61
+ echo wait_pid $pid $try_kill $timeout $force $countdown
62
+ if [ -e /proc/$pid ]; then
63
+ if [ "$try_kill" = "1" ]; then
64
+ echo "Killing $pidfile: $pid "
65
+ kill $pid
66
+ fi
67
+ while [ -e /proc/$pid ]; do
68
+ sleep 0.1
69
+ [ "$countdown" != '0' -a $(( $countdown % 10 )) = '0' ] && echo -n .
70
+ if [ $timeout -gt 0 ]; then
71
+ if [ $countdown -eq 0 ]; then
72
+ if [ "$force" = "1" ]; then
73
+ echo -ne "\nKill timed out, using kill -9 on $pid... "
74
+ kill -9 $pid
75
+ sleep 0.5
76
+ fi
77
+ break
78
+ else
79
+ countdown=$(( $countdown - 1 ))
80
+ fi
81
+ fi
82
+ done
83
+ if [ -e /proc/$pid ]; then
84
+ echo "Timed Out"
85
+ else
86
+ echo "Stopped"
87
+ fi
88
+ else
89
+ echo "Process $pid is not running"
90
+ echo "Attempting to kill pid anyway..."
91
+ kill $pid
92
+ fi
93
+ }
94
+
95
+ wait_pidfile() {
96
+ pidfile=$1
97
+ try_kill=$2
98
+ timeout=${3:-0}
99
+ force=${4:-0}
100
+ countdown=$(( $timeout * 10 ))
101
+
102
+ if [ -f "$pidfile" ]; then
103
+ pid=$(head -1 "$pidfile")
104
+ if [ -z "$pid" ]; then
105
+ echo "Unable to get pid from $pidfile"
106
+ exit 1
107
+ fi
108
+
109
+ wait_pid $pid $try_kill $timeout $force
110
+
111
+ rm -f $pidfile
112
+ else
113
+ echo "Pidfile $pidfile doesn't exist"
114
+ fi
115
+ }
116
+
117
+ kill_and_wait() {
118
+ pidfile=$1
119
+ # Monit default timeout for start/stop is 30s
120
+ # Append 'with timeout {n} seconds' to monit start/stop program configs
121
+ timeout=${2:-25}
122
+ force=${3:-1}
123
+ if [[ -f ${pidfile} ]]
124
+ then
125
+ wait_pidfile $pidfile 1 $timeout $force
126
+ else
127
+ # TODO assume $1 is something to grep from 'ps ax'
128
+ pid="$(ps auwwx | grep "$1" | awk '{print $2}')"
129
+ wait_pid $pid 1 $timeout $force
130
+ fi
131
+ }
132
+
133
+ check_nfs_mount() {
134
+ opts=$1
135
+ exports=$2
136
+ mount_point=$3
137
+
138
+ if grep -qs $mount_point /proc/mounts; then
139
+ echo "Found NFS mount $mount_point"
140
+ else
141
+ echo "Mounting NFS..."
142
+ mount $opts $exports $mount_point
143
+ if [ $? != 0 ]; then
144
+ echo "Cannot mount NFS from $exports to $mount_point, exiting..."
145
+ exit 1
146
+ fi
147
+ fi
148
+ }
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+ # USAGE monit_debugger <label> command to run
3
+ mkdir -p /var/vcap/sys/log/monit
4
+ {
5
+ echo "MONIT-DEBUG date"
6
+ date
7
+ echo "MONIT-DEBUG env"
8
+ env
9
+ echo "MONIT-DEBUG $@"
10
+ $2 $3 $4 $5 $6 $7
11
+ R=$?
12
+ echo "MONIT-DEBUG exit code $R"
13
+ } >/var/vcap/sys/log/monit/monit_debugger.$1.log 2>&1
@@ -0,0 +1,41 @@
1
+ #!/bin/bash
2
+
3
+ set -e # exit immediately if a simple command exits with a non-zero status
4
+ set -u # report the usage of uninitialized variables
5
+
6
+ # Setup env vars and folders for the webapp_ctl script
7
+ source /var/vcap/jobs/<%= job_name %>/bin/ctl_setup.sh
8
+
9
+ # Override ctl_setup.sh defaults:
10
+ redirect_output 'nginx'
11
+ PIDFILE=$RUN_DIR/nginx.pid
12
+
13
+ case $1 in
14
+
15
+ start)
16
+ pid_guard $PIDFILE "nginx for $JOB_NAME"
17
+
18
+ echo $$ > $PIDFILE
19
+
20
+ for dir in $UPLOADS_DIR $STAGED_UPLOADS_DIR
21
+ do
22
+ mkdir -p ${dir}
23
+ done
24
+
25
+ exec /var/vcap/packages/nginx_next/sbin/nginx \
26
+ -c $JOB_DIR/config/nginx.conf \
27
+ >>$LOG_DIR/nginx.stdout.log \
28
+ 2>>$LOG_DIR/nginx.stderr.log
29
+ ;;
30
+
31
+ stop)
32
+ echo "Stopping nginx"
33
+ kill_and_wait $PIDFILE
34
+ ;;
35
+
36
+ *)
37
+ echo "Usage: nginx_ctl {start|stop}"
38
+
39
+ ;;
40
+
41
+ esac
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Sets up ctl script for a Rails/Rack application
4
+ # * sets up $RAILS_ENV, $RACK_ENV
5
+ # * specifically sets $BUNDLE_GEMFILE, if $WEBAPP_DIR set
6
+
7
+ # Default properties:
8
+ #
9
+ # properties:
10
+ # webapp:
11
+ # migrate: false
12
+ # migration_command: rake db:migrate
13
+
14
+ migrate='<%= (properties.webapp && properties.webapp.migrate) || "false" %>'
15
+ migration_command='<%= (properties.webapp && properties.webapp.migration_command) || "rake db:migrate" %>'
16
+
17
+ export RAILS_ENV=production
18
+ export RACK_ENV=${RAILS_ENV}
19
+ if [[ "$WEBAPP_DIR" != '' ]]
20
+ then
21
+ export BUNDLE_GEMFILE=$WEBAPP_DIR/Gemfile
22
+ fi
23
+
24
+ function run_migrations() {
25
+ if [[ "${migrate}" = "true" || "${migrate}" = "1" || "${migrate}" = "yes" ]]
26
+ then
27
+ wait_for_database
28
+
29
+ echo "Running migrations"
30
+ bundle exec ${migration_command} \
31
+ >>$LOG_DIR/db_migrate.stdout.log \
32
+ 2>>$LOG_DIR/db_migrate.stderr.log
33
+ if [ $? != 0 ]; then
34
+ echo "Migrations failed"
35
+ exit 1
36
+ fi
37
+ else
38
+ echo "Skipping migrations"
39
+ fi
40
+ }