sombrero 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Rakefile +1 -2
- data/app/.gitignore +6 -0
- data/app/.pryrc +1 -0
- data/app/Gemfile +6 -0
- data/app/Rakefile +1 -0
- data/app/base/base_controller.rb +3 -0
- data/app/base/boot.rb +2 -0
- data/app/base/helpers/application_helpers.rb +1 -0
- data/app/base/load_controllers.rb +2 -0
- data/app/base/rtcp_controller.rb +22 -0
- data/app/config/config.rb +11 -0
- data/app/config/config.yml +11 -0
- data/app/config/env/development.yml +0 -0
- data/app/config/env/production.yml +0 -0
- data/app/config/env/stage.yml +0 -0
- data/app/config/env/test.yml +0 -0
- data/app/config.ru +3 -0
- data/app/core/Gemfile +5 -0
- data/app/core/boot.rb +17 -0
- data/app/core/client/activity_observer.coffee +37 -0
- data/app/core/client/api.coffee +248 -0
- data/app/core/client/channels.coffee +37 -0
- data/app/core/client/load.coffee +20 -0
- data/app/core/client/page.coffee +68 -0
- data/app/core/client/polyfills/array.compact.coffee +4 -0
- data/app/core/client/polyfills/array.compact_join.coffee +4 -0
- data/app/core/client/polyfills/number.to_money.coffee +3 -0
- data/app/core/client/polyfills/string.capitalize.coffee +4 -0
- data/app/core/client/polyfills/string.strip.coffee +5 -0
- data/app/core/client/polyfills.coffee +6 -0
- data/app/core/client/render.coffee +57 -0
- data/app/core/client/util/alert.coffee +50 -0
- data/app/core/client/util/datetime.coffee +47 -0
- data/app/core/client/util.coffee +38 -0
- data/app/core/generate_controllers_map.rb +4 -0
- data/app/core/generate_webpack_setup.rb +4 -0
- data/app/core/load.rb +5 -0
- data/app/core/load_controllers.rb +16 -0
- data/app/package.json +5 -0
- data/app/webpack.config.js +51 -0
- data/bin/sombrero +5 -0
- data/docker/Dockerfile +5 -0
- data/docker/base/Dockerfile +3 -0
- data/docker/base/build +10 -0
- data/docker/base/build.sh +25 -0
- data/docker/cleanup +7 -0
- data/docker/run +68 -0
- data/docker/skel/build.sh +1 -0
- data/docker/skel/config.yml +24 -0
- data/docker/skel/prepare_build.sh +5 -0
- data/docker/skel/start.sh +1 -0
- data/docker/start +7 -0
- data/lib/sombrero/{version.rb → app.rb} +3 -1
- data/lib/sombrero/base_controller.rb +5 -0
- data/lib/sombrero/cli/app/install.rb +38 -0
- data/lib/sombrero/cli/app/update.rb +20 -0
- data/lib/sombrero/cli/app.rb +10 -0
- data/lib/sombrero/cli/docker/build.rb +170 -0
- data/lib/sombrero/cli/docker/install.rb +23 -0
- data/lib/sombrero/cli/docker.rb +14 -0
- data/lib/sombrero/cli.rb +128 -0
- data/lib/sombrero/rtcp_controller.rb +93 -0
- data/lib/sombrero.rb +110 -2
- data/sombrero.gemspec +6 -1
- metadata +91 -4
@@ -0,0 +1,50 @@
|
|
1
|
+
_ =
|
2
|
+
isObject: require('lodash/isObject')
|
3
|
+
isFunction: require('lodash/isFunction')
|
4
|
+
merge: require('lodash/merge')
|
5
|
+
#end
|
6
|
+
|
7
|
+
require 'sweetalert/dist/sweetalert.css'
|
8
|
+
Alert = require('sweetalert')
|
9
|
+
|
10
|
+
|
11
|
+
Alert.setDefaults
|
12
|
+
allowEscapeKey: false
|
13
|
+
allowOutsideClick: false
|
14
|
+
#end
|
15
|
+
|
16
|
+
|
17
|
+
module.exports =
|
18
|
+
alert: Alert
|
19
|
+
|
20
|
+
error: (text, opts = {}) ->
|
21
|
+
if _.isObject(text)
|
22
|
+
[text, opts] = [null, text]
|
23
|
+
Alert(_.merge({type: 'error', title: 'Error', text: text}, opts))
|
24
|
+
#end
|
25
|
+
|
26
|
+
|
27
|
+
warning: (title, opts = {}) ->
|
28
|
+
if _.isObject(title)
|
29
|
+
[title, opts] = [null, title]
|
30
|
+
Alert(_.merge({type: 'warning', title: title, text: null}, opts))
|
31
|
+
#end
|
32
|
+
|
33
|
+
|
34
|
+
success: (title = 'Done!', opts = {}) ->
|
35
|
+
if _.isObject(title)
|
36
|
+
[title, opts] = [null, title]
|
37
|
+
Alert(_.merge({title: title, text: null, showConfirmButton: false, timer: 1000, type: 'success'}, opts))
|
38
|
+
#end
|
39
|
+
|
40
|
+
|
41
|
+
confirm: (title, opts, cb) ->
|
42
|
+
if _.isFunction(title)
|
43
|
+
[title, opts, cb] = [null, {}, title]
|
44
|
+
else if _.isFunction(opts)
|
45
|
+
[opts, cb] = [null, opts]
|
46
|
+
title ||= 'This action is irreversible! Continue?'
|
47
|
+
Alert(_.merge({title: title, type: 'warning', showCancelButton: true}, opts), cb)
|
48
|
+
#end
|
49
|
+
|
50
|
+
#end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
Moment = require('moment')
|
2
|
+
|
3
|
+
current_year = ->
|
4
|
+
new Date().getFullYear()
|
5
|
+
#end
|
6
|
+
|
7
|
+
Api =
|
8
|
+
|
9
|
+
date_format: (x, skip_current_year = false) ->
|
10
|
+
date = Moment(x)
|
11
|
+
if skip_current_year && time.year() == current_year()
|
12
|
+
date.format('MMM Do')
|
13
|
+
else
|
14
|
+
date.format('MMM Do YYYY')
|
15
|
+
#end
|
16
|
+
|
17
|
+
|
18
|
+
datetime_format: (x, skip_current_year = false) ->
|
19
|
+
time = Moment(x)
|
20
|
+
if skip_current_year && time.year() == current_year()
|
21
|
+
time.format('MMMM D, h:mmA')
|
22
|
+
else
|
23
|
+
time.format('MMMM D YYYY, h:mmA')
|
24
|
+
#end
|
25
|
+
|
26
|
+
|
27
|
+
time_format: (x) ->
|
28
|
+
Moment(x).format('HH:mm')
|
29
|
+
#end
|
30
|
+
|
31
|
+
|
32
|
+
relative_time_format: (x) ->
|
33
|
+
return '' unless x
|
34
|
+
now = Moment()
|
35
|
+
_then = Moment(x)
|
36
|
+
diff = now.diff(_then, 'seconds')
|
37
|
+
|
38
|
+
if diff < 86400
|
39
|
+
_then.fromNow()
|
40
|
+
else if diff < 172800
|
41
|
+
_then.calendar(now)
|
42
|
+
else
|
43
|
+
Api.datetime_format(x)
|
44
|
+
#end
|
45
|
+
#end
|
46
|
+
|
47
|
+
module.exports = Api
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module.exports =
|
2
|
+
|
3
|
+
generate_uuid: ->
|
4
|
+
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace /[xy]/g, (c) ->
|
5
|
+
v = r = Math.random() * 16|0
|
6
|
+
v = (r&0x3|0x8) if c == 'x'
|
7
|
+
v.toString(16)
|
8
|
+
#end
|
9
|
+
|
10
|
+
|
11
|
+
shorten: (text, max_length = 50) ->
|
12
|
+
return unless text
|
13
|
+
text[0 .. max_length] + (if text.length > max_length then '...' else '')
|
14
|
+
#end
|
15
|
+
|
16
|
+
|
17
|
+
scroll_top: ->
|
18
|
+
window.scrollTo(0, 0)
|
19
|
+
#end
|
20
|
+
|
21
|
+
|
22
|
+
reload: ->
|
23
|
+
window.location.reload()
|
24
|
+
#end
|
25
|
+
|
26
|
+
|
27
|
+
popup: (url, width, height) ->
|
28
|
+
width ||= 800
|
29
|
+
height ||= 600
|
30
|
+
left = (screen.width / 2) - (width / 2)
|
31
|
+
top = (screen.height / 2) - (height / 2)
|
32
|
+
window.open url, '_blank', 'menubar=no' +
|
33
|
+
',width=' + width +
|
34
|
+
',height=' + height +
|
35
|
+
',left=' + left +
|
36
|
+
',top=' + top
|
37
|
+
#end
|
38
|
+
#end
|
data/app/core/load.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# DO NOT EDIT THIS FILE, all updates will be lost on next update.
|
2
|
+
# edit base/load_controllers.rb instead.
|
3
|
+
|
4
|
+
Dir.chdir File.expand_path('../..', __FILE__) do
|
5
|
+
|
6
|
+
require './base/base_controller'
|
7
|
+
require './base/rtcp_controller'
|
8
|
+
|
9
|
+
%w[
|
10
|
+
**/server.rb
|
11
|
+
].each_with_object([]) {|f,o| o.concat(Dir["./base/api/#{f}"])}.sort {|a,b|
|
12
|
+
a.split(/\/+/).size <=> b.split(/\/+/).size
|
13
|
+
}.each {|f| require(f)}
|
14
|
+
|
15
|
+
require './base/load_controllers'
|
16
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
var webpack = require('webpack'),
|
2
|
+
fs = require('fs'),
|
3
|
+
child_process = require('child_process')
|
4
|
+
;
|
5
|
+
|
6
|
+
if (process.env.APP_ENV == 'development') {
|
7
|
+
console.log('Generating controllers map...');
|
8
|
+
child_process.execSync('./core/generate_controllers_map.rb');
|
9
|
+
console.log('Generating webpack setup...');
|
10
|
+
child_process.execSync('./core/generate_webpack_setup.rb');
|
11
|
+
}
|
12
|
+
|
13
|
+
var setup = JSON.parse(fs.readFileSync('./webpack_setup.json'));
|
14
|
+
console.log(JSON.stringify(setup, null, 2))
|
15
|
+
|
16
|
+
module.exports = {
|
17
|
+
entry: setup.entries,
|
18
|
+
output: {
|
19
|
+
path: [setup.path, setup.url].join('/'),
|
20
|
+
filename: '[name].js',
|
21
|
+
publicPath: setup.url + '/', // trailing slash required
|
22
|
+
libraryTarget: 'commonjs2'
|
23
|
+
},
|
24
|
+
module: {
|
25
|
+
loaders: [
|
26
|
+
// { test: /\.coffee$/, loader: 'coffee-loader' },
|
27
|
+
// { test: /\.css$/, loader: 'style-loader!css-loader' },
|
28
|
+
// { test: /\.json$/, loader: 'json-loader' },
|
29
|
+
// { test: /\.otf($|\?)/, loader: require.resolve('file-loader') },
|
30
|
+
// { test: /\.ttf($|\?)/, loader: require.resolve('file-loader') },
|
31
|
+
// { test: /\.eot($|\?)/, loader: require.resolve('file-loader') },
|
32
|
+
// { test: /\.svg($|\?)/, loader: require.resolve('file-loader') },
|
33
|
+
// { test: /\.png($|\?)/, loader: require.resolve('url-loader') + '?limit=10000&mimetype=image/png' },
|
34
|
+
// { test: /\.jpg($|\?)/, loader: require.resolve('file-loader') },
|
35
|
+
// { test: /\.gif($|\?)/, loader: require.resolve('file-loader') },
|
36
|
+
// { test: /\.woff[2]?($|\?)/, loader: require.resolve('url-loader') + '?limit=10000&mimetype=application/font-woff' },
|
37
|
+
]
|
38
|
+
},
|
39
|
+
resolve: {
|
40
|
+
extensions: ['', '.js', '.css', '.json', '.coffee', '.html'],
|
41
|
+
alias: {
|
42
|
+
core: __dirname + '/core/client',
|
43
|
+
base: __dirname + '/base',
|
44
|
+
api: __dirname + '/base/api',
|
45
|
+
}
|
46
|
+
},
|
47
|
+
plugins: [
|
48
|
+
new webpack.optimize.DedupePlugin(),
|
49
|
+
new webpack.optimize.CommonsChunkPlugin('core', 'core.js'),
|
50
|
+
]
|
51
|
+
}
|
data/bin/sombrero
CHANGED
data/docker/Dockerfile
ADDED
data/docker/base/build
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#/usr/bin/env sh
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
for e in $(getent passwd | cut -d: -f1); do
|
6
|
+
[[ "$e" = "root" || "$e" = "nobody" ]] || ! deluser "$e"
|
7
|
+
done
|
8
|
+
|
9
|
+
for e in $(getent group | cut -d: -f1); do
|
10
|
+
[[ "$e" = "root" || "$e" = "nobody" ]] || ! delgroup "$e"
|
11
|
+
done
|
12
|
+
|
13
|
+
echo "http://dl-4.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
|
14
|
+
|
15
|
+
apk update
|
16
|
+
apk upgrade
|
17
|
+
|
18
|
+
apk add build-base runit nmap-ncat libxml2 libxml2-dev libxslt libxslt-dev \
|
19
|
+
ruby ruby-dev ruby-irb ruby-io-console ruby-bigdecimal \
|
20
|
+
nodejs nodejs-dev python git \
|
21
|
+
redis libpq postgresql-dev \
|
22
|
+
imagemagick imagemagick-dev
|
23
|
+
|
24
|
+
curl -fsSL curl.haxx.se/ca/cacert.pem -o "$(ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE')"
|
25
|
+
echo 'gem: --no-ri --no-rdoc' > /root/.gemrc
|
data/docker/cleanup
ADDED
data/docker/run
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
run() {
|
4
|
+
echo -e "\n$ $@"
|
5
|
+
"$@"
|
6
|
+
}
|
7
|
+
|
8
|
+
container_is_built() {
|
9
|
+
[[ -n $(docker ps -a | grep -E "\s$CONTAINER_NAME\s") ]]
|
10
|
+
}
|
11
|
+
|
12
|
+
container_is_running() {
|
13
|
+
[[ -n $(docker ps | grep -E "\s$CONTAINER_NAME\s") ]]
|
14
|
+
}
|
15
|
+
|
16
|
+
stop_container() {
|
17
|
+
run docker stop $CONTAINER_NAME
|
18
|
+
}
|
19
|
+
|
20
|
+
remove_container() {
|
21
|
+
run docker rm $CONTAINER_NAME
|
22
|
+
}
|
23
|
+
|
24
|
+
env_prompt() {
|
25
|
+
read APP_ENV
|
26
|
+
[ "$(echo " {environments} " | grep -E "\s$APP_ENV\s")" = "" ] && env_prompt
|
27
|
+
}
|
28
|
+
|
29
|
+
if [ "$APP_ENV" = "" ]; then
|
30
|
+
echo "APP_ENV not set, please use one of"
|
31
|
+
echo "{environments}"
|
32
|
+
echo -n "> "
|
33
|
+
env_prompt
|
34
|
+
fi
|
35
|
+
|
36
|
+
set -e
|
37
|
+
|
38
|
+
{container_definitions}
|
39
|
+
|
40
|
+
if [ "$CONTAINER_NAME" = "" ]; then
|
41
|
+
echo -e "\n\t::: $APP_ENV environment not supported. Use one of: {environments} :::\n"
|
42
|
+
exit 1
|
43
|
+
fi
|
44
|
+
|
45
|
+
APP_UID="$(id -u)"
|
46
|
+
APP_GID="$(id -g)"
|
47
|
+
APP_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})/{script_path_traversal}"; pwd)"
|
48
|
+
|
49
|
+
if [ "$APP_UID" = "0" ]; then
|
50
|
+
echo -e "\n\t::: No superpowers accepted here! Run this as a regular user :::\n"
|
51
|
+
exit 1
|
52
|
+
fi
|
53
|
+
|
54
|
+
run docker pull {image}
|
55
|
+
container_is_running && stop_container
|
56
|
+
container_is_built && remove_container
|
57
|
+
|
58
|
+
run docker run \
|
59
|
+
--name "$CONTAINER_NAME" \
|
60
|
+
-e APP_ENV="$APP_ENV" \
|
61
|
+
-e APP_UID="$APP_UID" \
|
62
|
+
-e APP_GID="$APP_GID" \
|
63
|
+
-e LANG="en_US.UTF-8" \
|
64
|
+
-e LC_ALL="en_US.UTF-8" \
|
65
|
+
-e LC_TYPE="en_US.UTF-8" \
|
66
|
+
-v "$APP_DIR":/app \
|
67
|
+
{run_opts} {image}
|
68
|
+
echo
|
@@ -0,0 +1 @@
|
|
1
|
+
# running inside container.
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# a image with this name will be built (see prepare_build.sh and build.sh)
|
2
|
+
IMAGE_NAME:
|
3
|
+
|
4
|
+
# the name of container to be run on your server(s).
|
5
|
+
# name depends on APP_ENV variable.
|
6
|
+
# you can add/remove environments but at least one is required.
|
7
|
+
CONTAINER_NAME:
|
8
|
+
development:
|
9
|
+
test:
|
10
|
+
stage:
|
11
|
+
production:
|
12
|
+
|
13
|
+
# path to app.
|
14
|
+
# should be absolute or relative to this file.
|
15
|
+
APP_DIR:
|
16
|
+
|
17
|
+
# a file with this name will be generated and installed inside APP_DIR.
|
18
|
+
RUN_SCRIPT: docker/run
|
19
|
+
|
20
|
+
# options passed to `docker build`
|
21
|
+
BUILD_OPTS: --force-rm --no-cache
|
22
|
+
|
23
|
+
# options passed to `docker run`
|
24
|
+
RUN_OPTS: -d --restart always
|
@@ -0,0 +1,5 @@
|
|
1
|
+
# running before image building started.
|
2
|
+
# will run inside building dir so copy into ./ any files you need for building.
|
3
|
+
# APP_DIR variable points to your app directory
|
4
|
+
# so use it to copy any files from your app into building dir.
|
5
|
+
# running outside container, e.g. on your dev machine.
|
@@ -0,0 +1 @@
|
|
1
|
+
# start your app
|
data/docker/start
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Sombrero
|
2
|
+
class CLI
|
3
|
+
class App
|
4
|
+
class Install
|
5
|
+
include InstallHelpers
|
6
|
+
|
7
|
+
def initialize dir, namespace
|
8
|
+
ensure_dirname_exists(dir)
|
9
|
+
assert_installable_dir(dir)
|
10
|
+
install(dir, namespace)
|
11
|
+
end
|
12
|
+
|
13
|
+
def install dir, namespace
|
14
|
+
src = dir.to_path == '.' ? BASE_DIR.to_path + '/.' : BASE_DIR
|
15
|
+
FileUtils.cp_r(src, dir)
|
16
|
+
FileUtils.chmod('+x', dir / 'core/generate_webpack_setup.rb')
|
17
|
+
FileUtils.chmod('+x', dir / 'core/generate_controllers_map.rb')
|
18
|
+
if namespace
|
19
|
+
%w[
|
20
|
+
base/base_controller.rb
|
21
|
+
base/rtcp_controller.rb
|
22
|
+
config/config.rb
|
23
|
+
].each do |file|
|
24
|
+
code = File.read(dir / file)
|
25
|
+
File.open dir / file, 'w' do |f|
|
26
|
+
f.puts "module #{namespace}"
|
27
|
+
code.split("\n").each {|l| f.puts " #{l}"}
|
28
|
+
f.puts "end"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
puts "Done. All files installed into #{dir}"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
module Sombrero
|
2
|
+
class CLI
|
3
|
+
module Docker
|
4
|
+
class Build
|
5
|
+
|
6
|
+
def initialize dir, args
|
7
|
+
check_working_dir(dir)
|
8
|
+
|
9
|
+
Dir.chdir dir do
|
10
|
+
check_config_file
|
11
|
+
|
12
|
+
config = load_config
|
13
|
+
validate_config(config)
|
14
|
+
|
15
|
+
build_dir = Pathname.new(File.expand_path('__tmpbuildir__'))
|
16
|
+
|
17
|
+
prepare_build_dir(build_dir)
|
18
|
+
|
19
|
+
install_files(build_dir)
|
20
|
+
|
21
|
+
app_dir = Pathname.new(File.expand_path(config['APP_DIR']))
|
22
|
+
|
23
|
+
unless skip_build?(args)
|
24
|
+
prepare_build(build_dir, app_dir)
|
25
|
+
|
26
|
+
image_built = build_image(build_dir, config['IMAGE_NAME'], config['BUILD_OPTS'])
|
27
|
+
|
28
|
+
if image_built && push_opted?(args)
|
29
|
+
push_image(config['IMAGE_NAME'])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
install_run_script(app_dir, *config.values_at('IMAGE_NAME', 'CONTAINER_NAME', 'RUN_SCRIPT', 'RUN_OPTS'))
|
34
|
+
|
35
|
+
FileUtils.rm_rf(build_dir)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def push_opted? args
|
40
|
+
args.find {|a| a == '-p'}
|
41
|
+
end
|
42
|
+
|
43
|
+
def skip_build? args
|
44
|
+
args.find {|a| a == '-u'}
|
45
|
+
end
|
46
|
+
|
47
|
+
def check_working_dir dir
|
48
|
+
return if File.directory?(dir)
|
49
|
+
puts "#{dir} should be a directory"
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def check_config_file
|
54
|
+
return if File.file?(CONFIG_FILE)
|
55
|
+
puts "#{dir}/config.yml file is missing"
|
56
|
+
exit 1
|
57
|
+
end
|
58
|
+
|
59
|
+
def load_config
|
60
|
+
YAML.load(File.read(CONFIG_FILE))
|
61
|
+
end
|
62
|
+
|
63
|
+
def validate_config config
|
64
|
+
{
|
65
|
+
'IMAGE_NAME' => :validate_config__image_name,
|
66
|
+
'CONTAINER_NAME' => :validate_config__container_name,
|
67
|
+
'APP_DIR' => :validate_config__app_dir,
|
68
|
+
'RUN_SCRIPT' => :validate_config__run_script,
|
69
|
+
}.each_pair do |key,validator|
|
70
|
+
next if send(validator, config[key])
|
71
|
+
puts "", "\t::: Please set #{key} in config.yml :::", ""
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def validate_config__image_name value
|
77
|
+
!value.nil? && !value.empty?
|
78
|
+
end
|
79
|
+
|
80
|
+
def validate_config__container_name value
|
81
|
+
!value.nil? && !value.empty? && value.values.any?
|
82
|
+
end
|
83
|
+
|
84
|
+
def validate_config__app_dir value
|
85
|
+
!value.nil? && !value.empty?
|
86
|
+
end
|
87
|
+
|
88
|
+
def validate_config__run_script value
|
89
|
+
!value.nil? && !value.empty?
|
90
|
+
end
|
91
|
+
|
92
|
+
def prepare_build_dir dir
|
93
|
+
FileUtils.rm_rf(dir)
|
94
|
+
FileUtils.mkdir_p(dir / 'build')
|
95
|
+
end
|
96
|
+
|
97
|
+
def install_files dir
|
98
|
+
install_dockerfile(dir)
|
99
|
+
install_start_file(dir)
|
100
|
+
install_build_files(dir)
|
101
|
+
install_cleanup_file(dir)
|
102
|
+
end
|
103
|
+
|
104
|
+
def install_dockerfile dir
|
105
|
+
FileUtils.cp(BASE_DIR / 'Dockerfile', dir)
|
106
|
+
end
|
107
|
+
|
108
|
+
def install_start_file dir
|
109
|
+
File.open dir / 'start', 'w' do |f|
|
110
|
+
f << File.read(BASE_DIR / 'start').sub('{start}', File.read(START_FILE))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def install_build_files dir
|
115
|
+
FileUtils.cp(PREPARE_BUILD_FILE, dir / 'build')
|
116
|
+
FileUtils.cp(BUILD_FILE, dir / 'build/build')
|
117
|
+
end
|
118
|
+
|
119
|
+
def install_cleanup_file dir
|
120
|
+
FileUtils.cp(BASE_DIR / 'cleanup', dir / 'build')
|
121
|
+
end
|
122
|
+
|
123
|
+
def prepare_build dir, app_dir
|
124
|
+
Dir.chdir dir / 'build' do
|
125
|
+
CLI.run "APP_DIR=#{app_dir} #{PREPARE_BUILD_FILE}"
|
126
|
+
exit 1 unless $? && $?.success?
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def build_image dir, image_name, build_opts
|
131
|
+
CLI.run "docker build -t #{image_name} #{build_opts} '#{dir}'"
|
132
|
+
$? && $?.success?
|
133
|
+
end
|
134
|
+
|
135
|
+
def push_image image_name
|
136
|
+
CLI.run "docker push #{image_name}"
|
137
|
+
$? && $?.success?
|
138
|
+
end
|
139
|
+
|
140
|
+
def install_run_script app_dir, image_name, container_name, run_script, run_opts
|
141
|
+
FileUtils.mkdir_p(app_dir / File.dirname(run_script))
|
142
|
+
|
143
|
+
script_path = app_dir / run_script
|
144
|
+
|
145
|
+
File.open script_path, 'w' do |f|
|
146
|
+
f << File.read(BASE_DIR / 'run').
|
147
|
+
gsub('{image}', image_name).
|
148
|
+
gsub('{script_path_traversal}', script_path_traversal(run_script)).
|
149
|
+
gsub('{run_opts}', run_opts).
|
150
|
+
gsub('{environments}', container_name.keys.join(' ')).
|
151
|
+
gsub('{container_definitions}', container_definitions(container_name))
|
152
|
+
end
|
153
|
+
|
154
|
+
FileUtils.chmod('+x', script_path)
|
155
|
+
end
|
156
|
+
|
157
|
+
def container_definitions container_name
|
158
|
+
container_name.map do |kv|
|
159
|
+
'[ "$APP_ENV" = "%s" ] && CONTAINER_NAME="%s"' % kv
|
160
|
+
end.join("\n")
|
161
|
+
end
|
162
|
+
|
163
|
+
def script_path_traversal run_script
|
164
|
+
run_script.gsub(/\A\/+|\/+\Z/, '').scan(/\/+/).map {'..'}*'/'
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|