sombrero 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|